A simple solution would be to check that p1 actually exited (whether successful or because of a timeout) and then stop the pipeline to avoid defunct processes. The subprocess module offers the wait() function for this: https://docs.python.org/3/library/subprocess.html#subprocess.Popen.wait
Christian's observation is right, the pipeline gets set up and both processes get started, but the code never looks at the returncode of the first process (p1) and only returns the returncode of the second process (p2): https:/ /opendev. org/openstack/ cinder/ src/commit/ 3b9cc13a9466801 8d8e0aec2dc9972 62c9c654a8/ cinder/ backup/ drivers/ ceph.py# L616
A simple solution would be to check that p1 actually exited (whether successful or because of a timeout) and then stop the pipeline to avoid defunct processes. The subprocess module offers the wait() function for this: https:/ /docs.python. org/3/library/ subprocess. html#subprocess .Popen. wait