Revision 8f765069
b/daemons/ganeti-noded | ||
---|---|---|
26 | 26 |
|
27 | 27 |
import os |
28 | 28 |
import sys |
29 |
import resource |
|
30 | 29 |
import traceback |
31 | 30 |
import BaseHTTPServer |
32 | 31 |
import simplejson |
... | ... | |
554 | 553 |
|
555 | 554 |
# become a daemon |
556 | 555 |
if options.fork: |
557 |
createDaemon()
|
|
556 |
utils.Daemonize(logfile=constants.LOG_NODESERVER)
|
|
558 | 557 |
|
559 | 558 |
logger.SetupLogging(twisted_workaround=True, debug=options.debug, |
560 | 559 |
program="ganeti-noded") |
... | ... | |
563 | 562 |
httpd.serve_forever() |
564 | 563 |
|
565 | 564 |
|
566 |
def createDaemon(): |
|
567 |
"""Detach a process from the controlling terminal and run it in the |
|
568 |
background as a daemon. |
|
569 |
|
|
570 |
""" |
|
571 |
UMASK = 077 |
|
572 |
WORKDIR = "/" |
|
573 |
# Default maximum for the number of available file descriptors. |
|
574 |
if 'SC_OPEN_MAX' in os.sysconf_names: |
|
575 |
try: |
|
576 |
MAXFD = os.sysconf('SC_OPEN_MAX') |
|
577 |
if MAXFD < 0: |
|
578 |
MAXFD = 1024 |
|
579 |
except OSError: |
|
580 |
MAXFD = 1024 |
|
581 |
else: |
|
582 |
MAXFD = 1024 |
|
583 |
# The standard I/O file descriptors are redirected to /dev/null by default. |
|
584 |
#REDIRECT_TO = getattr(os, "devnull", "/dev/null") |
|
585 |
REDIRECT_TO = constants.LOG_NODESERVER |
|
586 |
try: |
|
587 |
pid = os.fork() |
|
588 |
except OSError, e: |
|
589 |
raise Exception("%s [%d]" % (e.strerror, e.errno)) |
|
590 |
if (pid == 0): # The first child. |
|
591 |
os.setsid() |
|
592 |
try: |
|
593 |
pid = os.fork() # Fork a second child. |
|
594 |
except OSError, e: |
|
595 |
raise Exception("%s [%d]" % (e.strerror, e.errno)) |
|
596 |
if (pid == 0): # The second child. |
|
597 |
os.chdir(WORKDIR) |
|
598 |
os.umask(UMASK) |
|
599 |
else: |
|
600 |
# exit() or _exit()? See below. |
|
601 |
os._exit(0) # Exit parent (the first child) of the second child. |
|
602 |
else: |
|
603 |
os._exit(0) # Exit parent of the first child. |
|
604 |
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] |
|
605 |
if (maxfd == resource.RLIM_INFINITY): |
|
606 |
maxfd = MAXFD |
|
607 |
|
|
608 |
# Iterate through and close all file descriptors. |
|
609 |
for fd in range(0, maxfd): |
|
610 |
try: |
|
611 |
os.close(fd) |
|
612 |
except OSError: # ERROR, fd wasn't open to begin with (ignored) |
|
613 |
pass |
|
614 |
os.open(REDIRECT_TO, os.O_RDWR|os.O_CREAT|os.O_APPEND, 0600) |
|
615 |
# Duplicate standard input to standard output and standard error. |
|
616 |
os.dup2(0, 1) # standard output (1) |
|
617 |
os.dup2(0, 2) # standard error (2) |
|
618 |
return(0) |
|
619 |
|
|
620 |
|
|
621 | 565 |
if __name__ == '__main__': |
622 | 566 |
main() |
b/lib/utils.py | ||
---|---|---|
38 | 38 |
import itertools |
39 | 39 |
import select |
40 | 40 |
import fcntl |
41 |
import resource |
|
41 | 42 |
|
42 | 43 |
from cStringIO import StringIO |
43 | 44 |
|
... | ... | |
1080 | 1081 |
return False |
1081 | 1082 |
time.sleep(duration) |
1082 | 1083 |
return True |
1084 |
|
|
1085 |
|
|
1086 |
def Daemonize(logfile): |
|
1087 |
"""Daemonize the current process. |
|
1088 |
|
|
1089 |
This detaches the current process from the controlling terminal and |
|
1090 |
runs it in the background as a daemon. |
|
1091 |
|
|
1092 |
""" |
|
1093 |
UMASK = 077 |
|
1094 |
WORKDIR = "/" |
|
1095 |
# Default maximum for the number of available file descriptors. |
|
1096 |
if 'SC_OPEN_MAX' in os.sysconf_names: |
|
1097 |
try: |
|
1098 |
MAXFD = os.sysconf('SC_OPEN_MAX') |
|
1099 |
if MAXFD < 0: |
|
1100 |
MAXFD = 1024 |
|
1101 |
except OSError: |
|
1102 |
MAXFD = 1024 |
|
1103 |
else: |
|
1104 |
MAXFD = 1024 |
|
1105 |
|
|
1106 |
# this might fail |
|
1107 |
pid = os.fork() |
|
1108 |
if (pid == 0): # The first child. |
|
1109 |
os.setsid() |
|
1110 |
# this might fail |
|
1111 |
pid = os.fork() # Fork a second child. |
|
1112 |
if (pid == 0): # The second child. |
|
1113 |
os.chdir(WORKDIR) |
|
1114 |
os.umask(UMASK) |
|
1115 |
else: |
|
1116 |
# exit() or _exit()? See below. |
|
1117 |
os._exit(0) # Exit parent (the first child) of the second child. |
|
1118 |
else: |
|
1119 |
os._exit(0) # Exit parent of the first child. |
|
1120 |
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] |
|
1121 |
if (maxfd == resource.RLIM_INFINITY): |
|
1122 |
maxfd = MAXFD |
|
1123 |
|
|
1124 |
# Iterate through and close all file descriptors. |
|
1125 |
for fd in range(0, maxfd): |
|
1126 |
try: |
|
1127 |
os.close(fd) |
|
1128 |
except OSError: # ERROR, fd wasn't open to begin with (ignored) |
|
1129 |
pass |
|
1130 |
os.open(logfile, os.O_RDWR|os.O_CREAT|os.O_APPEND, 0600) |
|
1131 |
# Duplicate standard input to standard output and standard error. |
|
1132 |
os.dup2(0, 1) # standard output (1) |
|
1133 |
os.dup2(0, 2) # standard error (2) |
|
1134 |
return 0 |
Also available in: Unified diff