def main(): args = sys.argv[1:] print("subreaper-proxy: running '%s'" % (" ".join(args))) prctl.set_child_subreaper(1) os.execv(args[0], args)
def main(): args = sys.argv[1:] print "subreaper-proxy: running '%s'" % (" ".join(args)) prctl.set_child_subreaper(1) os.execv(args[0], args)
def main(runtime=['runc'], container_id=None): if container_id is None: container_id = _uuid.uuid4().hex _signal.signal(_signal.SIGCHLD, _reap) _prctl.set_child_subreaper(1) hooks = _get_hooks(path='hooks.json') status = _run(name='create', args=runtime + ['create', container_id]) if status != 0: _sys.exit(1) state_bytes, container_pid = _state( runtime=runtime, container_id=container_id) try: _run_hooks(event='prestart', hooks=hooks, state_bytes=state_bytes) except HookError as error: status = error.status _delete(runtime=runtime, container_id=container_id) _sys.exit(1) status = _run(name='start', args=runtime + ['start', container_id]) if status != 0: _delete(runtime=runtime, container_id=container_id) _sys.exit(1) _run_hooks( event='poststart', hooks=hooks, state_bytes=state_bytes, strict=False) _LOG.debug('waiting on container process {}'.format(container_pid)) while container_pid not in _REAPED_CHILDREN: _signal.pause() status = _REAPED_CHILDREN[container_pid] _LOG.debug('container process exited with {}'.format(status)) _run_hooks( event='poststop', hooks=hooks, state_bytes=state_bytes, strict=False) _delete(runtime=runtime, container_id=container_id) if status > 127: status = 127 _sys.exit(status)
def main(): setproctitle.setproctitle('angelize') global waidpids pidfile = None shcode = None waitpids = None args = sys.argv[1:] if not args: improper_args() first = args[0] if first == '--pidfile': if not args[1:]: improper_args() pidfile = args[1] commandline = args[2:] elif first == '--shcode': if not args[1:]: improper_args() shcode = args[1] commandline = args[2:] elif first == '--help': print_help() exit() elif first[0:1] == '-': improper_args() else: commandline = args if not commandline: improper_args() # very important, we register with Linux to become the subreaper of the the descendant process tree # anything double forking from this point will reparent to this process, not pid1 prctl.set_child_subreaper(True) # we call the actual command that is expected to daemonize itself # if it exits with an error we assume the damonization some-how failed and exit with the same error errcode = subprocess.call(commandline) if errcode != 0: exit(errcode) if pidfile: with open(pidfile) as fp: waitpids = [int(line.strip()) for line in fp] elif shcode: waitpids = [ int(line.strip()) for line in subprocess.check_output( ['sh', '-c', shcode]).split('\n') if line.strip() ] else: import psutil waitpids = [child.pid for child in psutil.Process().children()] signal_forwarder = make_signal_forwarder(waitpids) for signum in forwarding_signals: signal.signal(signum, signal_forwarder) exit(wait_processes(waitpids))
def test_child_subreaper(self): self.assertEqual(prctl.get_child_subreaper(), 0) prctl.set_child_subreaper(1) self.assertEqual(prctl.get_child_subreaper(), 1) prctl.set_child_subreaper(0)
def dfork(args: t.List[t.Union[bytes, str, os.PathLike]], env={}, fds={}, cwd=None, flags=os.O_CLOEXEC) -> t.Tuple[int, int]: """Create an fd-managed process, and return the fd. See the documentation of the "supervise" utility for usage of the returned fd. The returned fd is both the read end of the statusfd and the write end of the controlfd. Note that just because this returns, doesn't mean the process started successfully. This is a "low-level" function. The returned fd may immediately return POLLHUP, without ever returning a pid. The Process() class provides more guarantees. :param args: Arguments to execute. The first should point to an executable locatable by execvp, possible with the updated PATH and cwd specified by the env and cwd parameters. :type args: ``[PathLike or str or bytes]`` :param env: A dictionary of updates to be performed to the environment. This is only updates; clearing the environment is not supported. :type env: ``{ str: str }`` :param fds: A dictionary of updates to be performed to the fds by update_fds. If an fd is mapped to None, it will be closed. :type fds: ``{ int: int/None/object with fileno() }`` :param cwd: The working directory to change to. :type cwd: ``PathLike or str or bytes`` :param flags: Additional flags to set on the fd. Linux supports O_CLOEXEC, O_NONBLOCK. :type cwd: ``str`` :returns: int, int: The new file descriptor for tracking the process, and the pid of the new process. """ # validate arguments so we don't spuriously call fork args = [os.fspath(arg) for arg in args] if cwd: cwd = os.fspath(cwd) for var in env: if not isinstance(var, str): raise TypeError("env key is not a string: {}".format(var)) if not isinstance(env[var], str): raise TypeError("env value is not a string: {}".format(env[var])) for fd in fds: if not isinstance(fd, int): raise TypeError("fds key is not an int: {}".format(fd)) source_fd = fds[fd] if source_fd is None: continue fd_fileno = fileno(source_fd) # test that all file descriptors are open if not is_valid_fd(fd_fileno): raise ValueError("fds[{}] file is closed: {}".format( fd, source_fd)) executable = shutil.which(args[0], path=env.get("PATH", os.environ["PATH"])) if not executable: raise OSError(errno.ENOENT, "Executable not found in PATH", args[0]) args[0] = executable try: parent_side, child_side = socket.socketpair( socket.AF_UNIX, socket.SOCK_SEQPACKET | flags, 0) # don't set O_CLOEXEC if the user didn't request it if not (flags & os.O_CLOEXEC): os.set_inheritable(parent_side.fileno(), True) with sfork.subprocess() as supervise_proc: os.close(parent_side.fileno()) os.setsid() prctl.set_child_subreaper(True) with sfork.subprocess() as child_proc: os.close(child_side.fileno()) if cwd: os.chdir(cwd) update_fds(fds) child_proc.exec(sfork.to_bytes(executable), [sfork.to_bytes(arg) for arg in args], envp={ **os.environ, **env }) update_fds({0: child_side, 1: child_side}) supervise_proc.exec(supervise_utility_location, [], envp={}) # we are now in the parent child_side.close() except: parent_side.close() child_side.close() raise return parent_side, child_proc.pid
from bcc.syscall import syscall_name, syscalls import json import os import prctl import operator import pwd from datetime import datetime from elftools.elf.elffile import ELFFile from elftools.common.py3compat import bytes2str if sys.version_info.major < 3: izip_longest = itertools.izip_longest else: izip_longest = itertools.zip_longest prctl.set_child_subreaper(1) #syscall = [] #method = [] #method_merged = [] #x_children = [] timeout = 500 #123 # signal handler def signal_ignore(signal, frame): print()