def terminate(self):
try:
os.kill(self.pid, signal.SIGTERM)
except OSError, e:
if e.errno == errno.ESRCH:
return # process already killed by someone else
if e.errno == errno.EPERM:
# this can only happen if the original session was started as
# a different user. e.g. if the broker has been restarted with
# --demote=<some other user>. but don't worry too much about it
# as sessions are eventually terminated anyway.
print(
'WARNING: session with PID=%d not terminated because it '
'is owned by a different user. did you restart a broker '
'as a different user?' % self.pid
)
return
raise e
python类ESRCH的实例源码
def kill_cmd(self):
if self.cmd_pid > 1:
try:
os.close(self.cmd_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
raise e
try:
os.kill(self.cmd_pid, signal.SIGKILL)
os.waitpid(self.cmd_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.cmd_pid = -1
def kill_cmd(self):
if self.cmd_pid > 1:
try:
os.close(self.cmd_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
raise e
try:
os.kill(self.cmd_pid, signal.SIGKILL)
os.waitpid(self.cmd_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.cmd_pid = -1
def _kill_ssh(self):
if self.ssh_pid > 1:
try:
os.kill(self.ssh_pid, signal.SIGTERM)
os.waitpid(self.ssh_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.self_pid = -1
try:
os.close(self.ssh_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
print 'WHAT?', e
raise e
def shutdown(self, details=None):
# terminate all processes started by the broker
if self.hsl:
self.hsl.terminate()
if self.brl:
self.brl.terminate()
if self.wlan_lister:
self.wlan_lister.terminate()
if self.pm_lister:
self.pm_lister.terminate()
self.stop_sharing()
for session in self.sessions.values():
try:
# send SIGTERM, not SIGKILL, so that Session.shutdown() runs
session[LOCAL].terminate()
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
Control.shutdown(self, details) # does not return. always do last
def close_session(self, authkey):
session = self.sessions[authkey] # (Session, RemoteSession) tuple
released = []
# loop through share allocators
for a in self.allocators:
allocator = self.allocators[a]
released.extend(self.allocators[a].close_session(session))
try:
session[LOCAL].terminate() # don't bother being nice.
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
del self.sessions[authkey]
# re-add released resources to the remote master broker if this broker
# is configured to share
if released and self.is_sharing():
self.update_sharing()
if not self.allocating:
# handover in progress. shut down when no sessions with allocations
# remain
if not self.sessions:
self.shutdown(Exit('broker restarted. please reconnect'))
def terminate(self):
try:
os.kill(self.pid, signal.SIGTERM)
except OSError, e:
if e.errno == errno.ESRCH:
return # process already killed by someone else
if e.errno == errno.EPERM:
# this can only happen if the original session was started as
# a different user. e.g. if the broker has been restarted with
# --demote=<some other user>. but don't worry too much about it
# as sessions are eventually terminated anyway.
print(
'WARNING: session with PID=%d not terminated because it '
'is owned by a different user. did you restart a broker '
'as a different user?' % self.pid
)
return
raise e
def __call__(self, fn):
def decorated_fn():
sock, port = find_free_port()
pipe = Pipe()
control = self.Class(port, 'password', sock, [], pipe)
control.start()
remote = RemoteControl(('', port), 'password', 5)
result = fn(control, remote, pipe)
try:
time.sleep(0.1)
control.terminate()
control.join()
except OSError, e:
if e.errno == errno.ESRCH:
pass # the test already killed the process
else:
raise e
return result
return decorated_fn
def _kill_ssh(self):
if self.ssh_pid > 1:
try:
os.kill(self.ssh_pid, signal.SIGTERM)
os.waitpid(self.ssh_pid, 0)
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
self.self_pid = -1
try:
os.close(self.ssh_fd)
except OSError, e:
if e.errno == errno.EBADF:
pass # already closed
else:
print 'WHAT?', e
raise e
def close_session(self, authkey):
session = self.sessions[authkey] # (Session, RemoteSession) tuple
released = []
# loop through share allocators
for a in self.allocators:
allocator = self.allocators[a]
released.extend(self.allocators[a].close_session(session))
try:
session[LOCAL].terminate() # don't bother being nice.
except OSError, e:
if e.errno not in [errno.ECHILD, errno.ESRCH]:
raise Exception('unhandled errno: %d' % e.errno)
del self.sessions[authkey]
# re-add released resources to the remote master broker if this broker
# is configured to share
if released and self.is_sharing():
self.update_sharing()
if not self.allocating:
# handover in progress. shut down when no sessions with allocations
# remain
if not self.sessions:
self.shutdown(Exit('broker restarted. please reconnect'))
def join(pid, timeout):
if pid == 0:
return
start = time.time()
while time.time() - start < timeout:
try:
proc = Process(pid)
except NoSuchProcess:
return
except IOError, e:
if e.errno == errno.ESRCH:
return
else:
raise e
time.sleep(0.5)
raise Timeout('timeout')
def __call__(self, fn):
def decorated_fn():
sock, port = find_free_port()
pipe = Pipe()
control = self.Class(port, 'password', sock, [], pipe)
control.start()
remote = RemoteControl(('', port), 'password', 5)
result = fn(control, remote, pipe)
try:
time.sleep(0.1)
control.terminate()
control.join()
except OSError, e:
if e.errno == errno.ESRCH:
pass # the test already killed the process
else:
raise e
return result
return decorated_fn
def terminate(self):
if not self.running:
return
warning("Terminate %s" % self)
done = False
try:
if self.is_stopped:
self.cont(SIGKILL)
else:
self.kill(SIGKILL)
except PtraceError, event:
if event.errno == ESRCH:
done = True
else:
raise event
if not done:
self.waitExit()
self._notRunning()
def checkPID(pidfile):
if not pidfile:
return
if os.path.exists(pidfile):
try:
pid = int(open(pidfile).read())
except ValueError:
sys.exit('Pidfile %s contains non-numeric value' % pidfile)
try:
os.kill(pid, 0)
except OSError, why:
if why[0] == errno.ESRCH:
# The pid doesnt exists.
log.msg('Removing stale pidfile %s' % pidfile, isError=True)
os.remove(pidfile)
else:
sys.exit("Can't check status of PID %s from pidfile %s: %s" %
(pid, pidfile, why[1]))
else:
sys.exit("""\
Another twistd server is running, PID %s\n
This could either be a previously started instance of your application or a
different application entirely. To start a new one, either run it in some other
directory, or use the --pidfile and --logfile parameters to avoid clashes.
""" % pid)
def _teardown_webserver(self):
LOG.info("Stopping stub web server ...")
try:
self.webserver.terminate()
for i in range(0, 15):
if self.webserver.poll() is not None:
LOG.info("Stub web server has stopped.")
break
time.sleep(1)
else:
LOG.warning(
'15 seconds have passed since sending SIGTERM to the stub '
'web server. It is still alive. Send SIGKILL.')
self.webserver.kill()
self.webserver.wait() # collect zombie
except OSError as e:
if e.errno == errno.ESRCH:
return
raise
def stop(self):
"""Terminate child processes and wait on each."""
self.running = False
LOG.debug("Stop services.")
for service in set(
[wrap.service for wrap in self.children.values()]):
service.stop()
LOG.debug("Killing children.")
for pid in self.children:
try:
os.kill(pid, signal.SIGTERM)
except OSError as exc:
if exc.errno != errno.ESRCH:
raise
# Wait for children to die
if self.children:
LOG.info(_LI('Waiting on %d children to exit'), len(self.children))
while self.children:
self._wait_child()
def memory_maps(self):
try:
raw = cext.proc_memory_maps(self.pid)
except OSError as err:
# XXX - can't use wrap_exceptions decorator as we're
# returning a generator; probably needs refactoring.
if err.errno in ACCESS_DENIED_SET:
raise AccessDenied(self.pid, self._name)
if err.errno == errno.ESRCH:
raise NoSuchProcess(self.pid, self._name)
raise
else:
for addr, perm, path, rss in raw:
path = convert_dos_path(path)
addr = hex(addr)
yield (addr, perm, path, rss)
def get_proc_inodes(self, pid):
inodes = defaultdict(list)
for fd in os.listdir("%s/%s/fd" % (self._procfs_path, pid)):
try:
inode = readlink("%s/%s/fd/%s" % (self._procfs_path, pid, fd))
except OSError as err:
# ENOENT == file which is gone in the meantime;
# os.stat('/proc/%s' % self.pid) will be done later
# to force NSP (if it's the case)
if err.errno in (errno.ENOENT, errno.ESRCH):
continue
elif err.errno == errno.EINVAL:
# not a link
continue
else:
raise
else:
if inode.startswith('socket:['):
# the process is using a socket
inode = inode[8:][:-1]
inodes[inode].append((pid, int(fd)))
return inodes
def get_all_inodes(self):
inodes = {}
for pid in pids():
try:
inodes.update(self.get_proc_inodes(pid))
except OSError as err:
# os.listdir() is gonna raise a lot of access denied
# exceptions in case of unprivileged user; that's fine
# as we'll just end up returning a connection with PID
# and fd set to None anyway.
# Both netstat -an and lsof does the same so it's
# unlikely we can do any better.
# ENOENT just means a PID disappeared on us.
if err.errno not in (
errno.ENOENT, errno.ESRCH, errno.EPERM, errno.EACCES):
raise
return inodes
def wrap_exceptions(fun):
"""Decorator which translates bare OSError and IOError exceptions
into NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except EnvironmentError as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if err.errno in (errno.ENOENT, errno.ESRCH):
raise NoSuchProcess(self.pid, self._name)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
def wrap_exceptions(fun):
"""Decorator which translates bare OSError exceptions into
NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except OSError as err:
if err.errno == errno.ESRCH:
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
def wrap_exceptions(fun):
"""Decorator which translates bare OSError exceptions into
NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except OSError as err:
if err.errno == errno.ESRCH:
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
def wrap_exceptions(fun):
"""Call callable into a try/except clause and translate ENOENT,
EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
"""
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except EnvironmentError as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if err.errno in (errno.ENOENT, errno.ESRCH):
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
def nice_get(self):
# For some reason getpriority(3) return ESRCH (no such process)
# for certain low-pid processes, no matter what (even as root).
# The process actually exists though, as it has a name,
# creation time, etc.
# The best thing we can do here appears to be raising AD.
# Note: tested on Solaris 11; on Open Solaris 5 everything is
# fine.
try:
return cext_posix.getpriority(self.pid)
except EnvironmentError as err:
# 48 is 'operation not supported' but errno does not expose
# it. It occurs for low system pids.
if err.errno in (errno.ENOENT, errno.ESRCH, 48):
if pid_exists(self.pid):
raise AccessDenied(self.pid, self._name)
raise
def memory_maps(self):
try:
raw = cext.proc_memory_maps(self.pid)
except OSError as err:
# XXX - can't use wrap_exceptions decorator as we're
# returning a generator; probably needs refactoring.
if err.errno in ACCESS_DENIED_SET:
raise AccessDenied(self.pid, self._name)
if err.errno == errno.ESRCH:
raise NoSuchProcess(self.pid, self._name)
raise
else:
for addr, perm, path, rss in raw:
path = _convert_raw_path(path)
addr = hex(addr)
yield (addr, perm, path, rss)
def get_all_inodes(self):
inodes = {}
for pid in pids():
try:
inodes.update(self.get_proc_inodes(pid))
except OSError as err:
# os.listdir() is gonna raise a lot of access denied
# exceptions in case of unprivileged user; that's fine
# as we'll just end up returning a connection with PID
# and fd set to None anyway.
# Both netstat -an and lsof does the same so it's
# unlikely we can do any better.
# ENOENT just means a PID disappeared on us.
if err.errno not in (
errno.ENOENT, errno.ESRCH, errno.EPERM, errno.EACCES):
raise
return inodes
def wrap_exceptions(fun):
"""Decorator which translates bare OSError and IOError exceptions
into NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except EnvironmentError as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if err.errno in (errno.ENOENT, errno.ESRCH):
raise NoSuchProcess(self.pid, self._name)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
def exe(self):
try:
return readlink("%s/%s/exe" % (self._procfs_path, self.pid))
except OSError as err:
if err.errno in (errno.ENOENT, errno.ESRCH):
# no such file error; might be raised also if the
# path actually exists for system processes with
# low pids (about 0-20)
if os.path.lexists("%s/%s" % (self._procfs_path, self.pid)):
return ""
else:
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
def wrap_exceptions(fun):
"""Decorator which translates bare OSError exceptions into
NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except OSError as err:
if err.errno == errno.ESRCH:
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper
def wrap_exceptions(fun):
"""Decorator which translates bare OSError exceptions into
NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except OSError as err:
if err.errno == errno.ESRCH:
if not pid_exists(self.pid):
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
return wrapper