mirror of
https://github.com/ceph/ceph
synced 2024-12-13 15:08:33 +00:00
c0f1ef7373
Some daemons (smbd) will try to read from stdin and check if its a socket, using that for sending/receiving messages. If /dev/null is used for stdin, the daemon aborts. This patch adds a 'nostdin' option to the daemon-helper so that the daemon can be started without /dev/null as stdin. Signed-off-by: Sam Lang <sam.lang@inktank.com>
81 lines
1.9 KiB
Python
Executable File
81 lines
1.9 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
"""
|
|
Helper script for running long-living processes.
|
|
|
|
(Name says daemon, but that is intended to mean "long-living", we
|
|
assume child process does not double-fork.)
|
|
|
|
We start the command passed as arguments, with /dev/null as stdin, and
|
|
then wait for EOF on stdin.
|
|
|
|
When EOF is seen on stdin, the child process is killed.
|
|
|
|
When the child process exits, this helper exits too.
|
|
"""
|
|
|
|
import fcntl
|
|
import os
|
|
import select
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
|
|
end_signal = signal.SIGKILL
|
|
if sys.argv[1] == "term":
|
|
end_signal = signal.SIGTERM
|
|
|
|
cmd_start = 2
|
|
|
|
nostdin = False
|
|
if sys.argv[cmd_start] == "nostdin":
|
|
nostdin = True
|
|
cmd_start += 1
|
|
|
|
proc = None
|
|
if nostdin:
|
|
proc = subprocess.Popen(
|
|
args=sys.argv[cmd_start:],
|
|
)
|
|
else:
|
|
with file('/dev/null', 'rb') as devnull:
|
|
proc = subprocess.Popen(
|
|
args=sys.argv[cmd_start:],
|
|
stdin=devnull,
|
|
)
|
|
|
|
flags = fcntl.fcntl(0, fcntl.F_GETFL)
|
|
fcntl.fcntl(0, fcntl.F_SETFL, flags | os.O_NDELAY)
|
|
|
|
saw_eof = False
|
|
while True:
|
|
r,w,x = select.select([0], [], [0], 0.2)
|
|
if r:
|
|
data = os.read(0, 1)
|
|
if not data:
|
|
saw_eof = True
|
|
proc.send_signal(end_signal)
|
|
break
|
|
|
|
if proc.poll() is not None:
|
|
# child exited
|
|
break
|
|
|
|
exitstatus = proc.wait()
|
|
if exitstatus > 0:
|
|
print >>sys.stderr, '{me}: command failed with exit status {exitstatus:d}'.format(
|
|
me=os.path.basename(sys.argv[0]),
|
|
exitstatus=exitstatus,
|
|
)
|
|
sys.exit(exitstatus)
|
|
elif exitstatus < 0:
|
|
if saw_eof and exitstatus == -end_signal:
|
|
# suppress error from the exit we intentionally caused
|
|
pass
|
|
else:
|
|
print >>sys.stderr, '{me}: command crashed with signal {signal:d}'.format(
|
|
me=os.path.basename(sys.argv[0]),
|
|
signal=-exitstatus,
|
|
)
|
|
sys.exit(1)
|