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