From 3693fed7541b1b95612166ce2534a07c6e43660e Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Fri, 18 Jun 2010 15:48:45 +0000 Subject: [PATCH] redirect the output of the initscripts (rc & rc.vinit) + try to detach --- python/vserver.py | 65 ++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/python/vserver.py b/python/vserver.py index 612e503..31361ce 100644 --- a/python/vserver.py +++ b/python/vserver.py @@ -133,7 +133,8 @@ class VServerConfig: class VServer: - INITSCRIPTS = [('/etc/rc.vinit', 'start'), + # adding the sliver name is for helping in the forensics + INITSCRIPTS = [('/etc/rc.vinit', 'start', '%(name)s'), ('/etc/rc.d/rc', '%(runlevel)d')] def __init__(self, name, vm_id = None, vm_running = None, logfile=None): @@ -154,12 +155,16 @@ class VServer: self.logfile = logfile # inspired from nodemanager's logger + def log_in_file (self, fd, msg): + if not msg: msg="\n" + if not msg.endswith('\n'): msg += '\n' + os.write(fd, '%s: %s' % (time.asctime(time.gmtime()), msg)) + def log(self,msg): if self.logfile: try: fd = os.open(self.logfile,os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0600) - if not msg.endswith('\n'): msg += '\n' - os.write(fd, '%s: %s' % (time.asctime(time.gmtime()), msg)) + self.log_in_file(fd,msg) os.close(fd) except: print '%s: (%s failed to open) %s'%(time.asctime(time.gmtime()),self.logfile,msg) @@ -372,36 +377,48 @@ class VServer: def enter(self): subprocess.call("/usr/sbin/vserver %s enter" % self.name, shell=True) + # detach the process that triggers the initscripts + # after http://code.activestate.com/recipes/278731/ def start(self, runlevel = 3): - if (os.fork() != 0): + if os.fork() != 0: # Parent should just return. self.vm_running = True return else: - # child process + os.setsid() + # first child process: fork again + if os.fork() != 0: + os._exit(0) # Exit parent (the first child) of the second child. + # the grandson is the working one + os.chdir('/') + os.umask(0) try: - subprocess.call("/usr/sbin/vserver %s start" % self.name, - shell=True) + # start the vserver + subprocess.call(["/usr/sbin/vserver",self.name,"start"]) # execute initscripts - for cmd in self.INITSCRIPTS: + for cmd_to_expand in self.INITSCRIPTS: + # enter vserver context + expand = { 'runlevel': runlevel, + 'name': self.name, } + cmd = [ x % expand for x in cmd_to_expand ] + cmd_name = os.path.basename(cmd[0]) + cmd_file = "/vservers/" + self.name + cmd[0] + if not os.path.isfile(cmd_file): + self.log("WARNING: could not find %s for %s" % (cmd_file, self.name)) + break + self.log("executing %r" % cmd) try: - # enter vserver context - arg_subst = { 'runlevel': runlevel } - cmd_args = [cmd[0]] + map(lambda x: x % arg_subst, cmd[1:]) - # add vserver name as the last command argument - cmd_args += [self.name] - cmd_file = "/vservers/" + self.name + cmd[0] - self.log(cmd_file) - if os.path.isfile(cmd_file): - self.log("executing '%s'" % " ".join(cmd_args)) - self.chroot_call(subprocess.call, " ".join(cmd_args), shell=True) - else: - self.log("WARNING: could not run %s on %s" % (cmd[0], self.name)) - except: - self.log(traceback.format_exc()) - - # we get here due to an exception in the top-level child process + logname='/vservers/%s/var/log/%s'%(self.name,cmd_name) + log_fd=os.open(logname,os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0600) + self.log_in_file(log_fd,"Running %r into %s"%(cmd,logname)) + self.chroot_call(subprocess.call,cmd, + stdout=log_fd,stderr=subprocess.STDOUT, + close_fds=True) + except: self.log(traceback.format_exc()) + finally: os.close(log_fd) + + # we get here due to an exception in the grandson process except Exception, ex: self.log(traceback.format_exc()) os._exit(0) -- 2.43.0