From: Patrick Donnelly Date: Thu, 11 Apr 2024 20:14:05 +0000 (-0400) Subject: test X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6a6cf8ac92f56fe23275ca394eefdc4b4d99a96d;p=teuthology.git test --- diff --git a/teuthology/task/install/bin/stdin-killer b/teuthology/task/install/bin/stdin-killer index d1c9ba4ec..16a5e0f15 100755 --- a/teuthology/task/install/bin/stdin-killer +++ b/teuthology/task/install/bin/stdin-killer @@ -146,8 +146,57 @@ def listen_for_events(sigfdr, p, timeout): NS.timeout, ) +def do_exec(NS): + cargs = NS.cmd + NS.args + popen_kwargs = { + "stdin": subprocess.PIPE, + } -if __name__ == "__main__": + if NS.setpgrp == "self": + pgrp = os.getpgrp() + if pgrp != os.getpid(): + os.setpgrp() + pgrp = os.getpgrp() + elif NS.setpgrp == "child": + popen_kwargs["preexec_fn"] = os.setpgrp + pgrp = None + elif NS.setpgrp == "no": + pgrp = 0 + else: + assert False + + log.debug("executing %s", cargs) + p = subprocess.Popen(cargs, **popen_kwargs) + if pgrp is None: + pgrp = p.pid + flags = fcntl.fcntl(p.stdin.fileno(), fcntl.F_GETFL) + fcntl.fcntl(p.stdin.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK) + + listen_for_events(sigfdr, p, NS.timeout) + + if p.returncode is None: + log.error("timeout expired: sending signal %d to command and myself", NS.signal) + if pgrp == 0: + os.kill(p.pid, NS.signal) + else: + os.killpg(pgrp, NS.signal) # should kill me too + os.kill(os.getpid(), NS.signal) # to exit abnormally with same signal + log.error("signal did not cause termination, sending myself SIGKILL") + os.kill(os.getpid(), signal.SIGKILL) # failsafe + rc = p.returncode + log.debug("rc = %d", rc) + assert rc is not None + if rc < 0: + log.error("command terminated with signal %d: sending same signal to myself!", -rc) + os.kill(os.getpid(), -rc) # kill myself with the same signal + log.error("signal did not cause termination, sending myself SIGKILL") + os.kill(os.getpid(), signal.SIGKILL) # failsafe + else: + log.info("command exited with status %d: exiting normally with same code!", rc) + return rc + + +def main(): signal.signal(signal.SIGPIPE, signal.SIG_IGN) try: (sigfdr, sigfdw) = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) @@ -186,6 +235,7 @@ if __name__ == "__main__": default=signal.SIGKILL, ) P.add_argument("--verbose", action="store_true", help="increase debugging") + P.add_argument("--reboot-on-exit0", dest='reboot', action="store_true", help="reboot command on exit 0") P.add_argument( "--setpgrp", action="store", @@ -214,50 +264,10 @@ if __name__ == "__main__": logargs["datefmt"] = "%Y-%m-%dT%H:%M:%S" logging.basicConfig(**logargs) - cargs = NS.cmd + NS.args - popen_kwargs = { - "stdin": subprocess.PIPE, - } - - if NS.setpgrp == "self": - pgrp = os.getpgrp() - if pgrp != os.getpid(): - os.setpgrp() - pgrp = os.getpgrp() - elif NS.setpgrp == "child": - popen_kwargs["preexec_fn"] = os.setpgrp - pgrp = None - elif NS.setpgrp == "no": - pgrp = 0 - else: - assert False - - log.debug("executing %s", cargs) - p = subprocess.Popen(cargs, **popen_kwargs) - if pgrp is None: - pgrp = p.pid - flags = fcntl.fcntl(p.stdin.fileno(), fcntl.F_GETFL) - fcntl.fcntl(p.stdin.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK) - - listen_for_events(sigfdr, p, NS.timeout) + while True: + rc = do_exec(NS) + if rc != 0 or not NS.reboot: + sys.exit(rc) - if p.returncode is None: - log.error("timeout expired: sending signal %d to command and myself", NS.signal) - if pgrp == 0: - os.kill(p.pid, NS.signal) - else: - os.killpg(pgrp, NS.signal) # should kill me too - os.kill(os.getpid(), NS.signal) # to exit abnormally with same signal - log.error("signal did not cause termination, sending myself SIGKILL") - os.kill(os.getpid(), signal.SIGKILL) # failsafe - rc = p.returncode - log.debug("rc = %d", rc) - assert rc is not None - if rc < 0: - log.error("command terminated with signal %d: sending same signal to myself!", -rc) - os.kill(os.getpid(), -rc) # kill myself with the same signal - log.error("signal did not cause termination, sending myself SIGKILL") - os.kill(os.getpid(), signal.SIGKILL) # failsafe - else: - log.info("command exited with status %d: exiting normally with same code!", rc) - sys.exit(rc) +if __name__ == "__main__": + main()