191 lines
6.1 KiB
Python
Executable File
191 lines
6.1 KiB
Python
Executable File
#!/usr/bin/python
|
|
# Copyright (c) 2010 OpenStack, LLC.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from __future__ import with_statement
|
|
import errno
|
|
import glob
|
|
import os
|
|
import resource
|
|
import signal
|
|
import sys
|
|
import time
|
|
|
|
ALL_SERVERS = ['account-auditor', 'account-server', 'container-auditor',
|
|
'container-replicator', 'container-server', 'container-updater',
|
|
'object-auditor', 'object-server', 'object-replicator', 'object-updater',
|
|
'proxy-server', 'account-replicator', 'auth-server', 'account-reaper']
|
|
GRACEFUL_SHUTDOWN_SERVERS = ['account-server', 'container-server',
|
|
'object-server', 'proxy-server', 'auth-server']
|
|
MAX_DESCRIPTORS = 32768
|
|
MAX_MEMORY = (1024 * 1024 * 1024) * 2 # 2 GB
|
|
|
|
_, server, command = sys.argv
|
|
if server == 'all':
|
|
servers = ALL_SERVERS
|
|
else:
|
|
if '-' not in server:
|
|
server = '%s-server' % server
|
|
servers = [server]
|
|
command = command.lower()
|
|
|
|
def pid_files(server):
|
|
if os.path.exists('/var/run/swift/%s.pid' % server):
|
|
pid_files = ['/var/run/swift/%s.pid' % server]
|
|
else:
|
|
pid_files = glob.glob('/var/run/swift/%s/*.pid' % server)
|
|
for pid_file in pid_files:
|
|
pid = int(open(pid_file).read().strip())
|
|
yield pid_file, pid
|
|
|
|
def do_start(server, once=False):
|
|
server_type = '-'.join(server.split('-')[:-1])
|
|
|
|
for pid_file, pid in pid_files(server):
|
|
if os.path.exists('/proc/%s' % pid):
|
|
print "%s appears to already be running: %s" % (server, pid_file)
|
|
return
|
|
else:
|
|
print "Removing stale pid file %s" % pid_file
|
|
os.unlink(pid_file)
|
|
|
|
try:
|
|
resource.setrlimit(resource.RLIMIT_NOFILE,
|
|
(MAX_DESCRIPTORS, MAX_DESCRIPTORS))
|
|
resource.setrlimit(resource.RLIMIT_DATA,
|
|
(MAX_MEMORY, MAX_MEMORY))
|
|
except ValueError:
|
|
print "Unable to increase file descriptor limit. Running as non-root?"
|
|
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
|
|
|
|
def write_pid_file(pid_file, pid):
|
|
dir, file = os.path.split(pid_file)
|
|
if not os.path.exists(dir):
|
|
try:
|
|
os.makedirs(dir)
|
|
except OSError, err:
|
|
if err.errno == errno.EACCES:
|
|
sys.exit('Unable to create %s. Running as non-root?' % dir)
|
|
fp = open(pid_file, 'w')
|
|
fp.write('%d\n' % pid)
|
|
fp.close()
|
|
|
|
def launch(ini_file, pid_file):
|
|
cmd = 'swift-%s' % server
|
|
args = [server, ini_file]
|
|
if once:
|
|
print 'Running %s once' % server
|
|
args.append('once')
|
|
else:
|
|
print 'Starting %s' % server
|
|
|
|
pid = os.fork()
|
|
if pid == 0:
|
|
os.setsid()
|
|
with open(os.devnull, 'r+b') as nullfile:
|
|
for desc in (0, 1, 2): # close stdio
|
|
try:
|
|
os.dup2(nullfile.fileno(), desc)
|
|
except OSError:
|
|
pass
|
|
try:
|
|
if once:
|
|
os.execlp('swift-%s' % server, server,
|
|
ini_file, 'once')
|
|
else:
|
|
os.execlp('swift-%s' % server, server, ini_file)
|
|
except OSError:
|
|
print 'unable to launch %s' % server
|
|
sys.exit(0)
|
|
else:
|
|
write_pid_file(pid_file, pid)
|
|
|
|
ini_file = '/etc/swift/%s-server.conf' % server_type
|
|
if os.path.exists(ini_file):
|
|
# single config file over-rides config dirs
|
|
pid_file = '/var/run/swift/%s.pid' % server
|
|
launch_args = [(ini_file, pid_file)]
|
|
elif os.path.exists('/etc/swift/%s-server/' % server_type):
|
|
# found config directory, searching for config file(s)
|
|
launch_args = []
|
|
for num, ini_file in enumerate(glob.glob('/etc/swift/%s-server/*.conf' % server_type)):
|
|
pid_file = '/var/run/swift/%s/%d.pid' % (server, num)
|
|
# start a server for each ini_file found
|
|
launch_args.append((ini_file, pid_file))
|
|
else:
|
|
# maybe there's a config file(s) out there, but I couldn't find it!
|
|
sys.exit('Unable to locate config file for %s. %s does not exist?' % (server, ini_file))
|
|
|
|
# start all servers
|
|
for ini_file, pid_file in launch_args:
|
|
launch(ini_file, pid_file)
|
|
|
|
def do_stop(server, graceful=False):
|
|
if graceful and server in GRACEFUL_SHUTDOWN_SERVERS:
|
|
sig = signal.SIGHUP
|
|
else:
|
|
sig = signal.SIGTERM
|
|
|
|
did_anything = False
|
|
pfiles = pid_files(server)
|
|
for pid_file, pid in pfiles:
|
|
did_anything = True
|
|
try:
|
|
print 'Stopping %s pid: %s signal: %s' % (server, pid, sig)
|
|
os.kill(pid, sig)
|
|
except OSError:
|
|
print "Process %d not running" % pid
|
|
try:
|
|
os.unlink(pid_file)
|
|
except OSError:
|
|
pass
|
|
for pid_file, pid in pfiles:
|
|
for _ in xrange(150): # 15 seconds
|
|
if not os.path.exists('/proc/%s' % pid):
|
|
break
|
|
time.sleep(0.1)
|
|
else:
|
|
print 'Waited 15 seconds for pid %s (%s) to die; giving up' % \
|
|
(pid, pid_file)
|
|
if not did_anything:
|
|
print 'No %s running' % server
|
|
|
|
if command == 'start':
|
|
for server in servers:
|
|
do_start(server)
|
|
|
|
if command == 'stop':
|
|
for server in servers:
|
|
do_stop(server)
|
|
|
|
if command == 'shutdown':
|
|
for server in servers:
|
|
do_stop(server, graceful=True)
|
|
|
|
if command == 'restart':
|
|
for server in servers:
|
|
do_stop(server)
|
|
for server in servers:
|
|
do_start(server)
|
|
|
|
if command == 'reload':
|
|
for server in servers:
|
|
do_stop(server, graceful=True)
|
|
do_start(server)
|
|
|
|
if command == 'once':
|
|
for server in servers:
|
|
do_start(server, once=True)
|