merged from 0.4
[util-vserver-pl.git] / python / vserver.py
index e4afacd..4724311 100644 (file)
@@ -151,9 +151,6 @@ def adjust_lim(goal, curr):
 
 class VServer:
 
-    INITSCRIPTS = [('/etc/rc.vinit', 'start'),
-                   ('/etc/rc.d/rc', '%(runlevel)d')]
-
     def __init__(self, name, vm_id = None, vm_running = None, logfile=None):
 
         self.name = name
@@ -172,12 +169,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)
@@ -207,7 +208,7 @@ class VServer:
                     resource.setrlimit(resource_type, lim)
             except OSError, e:
                 self.log("Error: setrlimit(%d, %s, %d, %d, %d): %s"
-                         % (self.ctx, type.lower(), hard, soft, min))
+                         % (self.ctx, type.lower(), hard, soft, min, e))
 
         return update
 
@@ -278,14 +279,14 @@ class VServer:
         os.chroot(self.dir)
         os.chdir("/")
 
-    def chroot_call(self, fn, *args):
+    def chroot_call(self, fn, *args, **kwargs):
 
         cwd_fd = os.open(".", os.O_RDONLY)
         try:
             root_fd = os.open("/", os.O_RDONLY)
             try:
                 self.__do_chroot()
-                result = fn(*args)
+                result = fn(*args, **kwargs)
             finally:
                 os.fchdir(root_fd)
                 os.chroot(".")
@@ -448,69 +449,33 @@ class VServer:
         self.__do_chroot()
         self.__do_chcontext(None)
 
-
+    # 2010 June 21 - Thierry 
+    # the slice initscript now gets invoked through rc - see sliver_vs.py in nodemanager
+    # and, rc is triggered as part of vserver .. start 
+    # so we don't have to worry about initscripts at all anymore here
     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:
-                # so we don't chcontext with priv'ed fds
-                close_nonstandard_fds()
-
-                # get a new session
-                os.setsid()
+                # start the vserver
+                subprocess.call(["/usr/sbin/vserver",self.name,"start"])
 
-                # open state file to record vserver info
-                state_file = open("/var/run/vservers/%s" % self.name, "w")
-
-                # use /dev/null for stdin, /var/log/boot.log for stdout/err
-                fd = os.open("/dev/null", os.O_RDONLY)
-                if fd != 0:
-                    os.dup2(fd, 0)
-                    os.close(fd)
-                # perform pre-init cleanup
-                self.__prep(runlevel)
-
-                self.config.cache_it()
-                self.__do_chroot()
-                removed = self.__cleanvar()
-
-                log = open("/var/log/nm", "a", 0)
-                if log.fileno() != 1:
-                    os.dup2(log.fileno(), 1)
-                os.dup2(1, 2)
-
-                print >>log, ("%s: removing %s" % 
-                                (time.asctime(time.gmtime()), removed))
-                print >>log, ("%s: starting the virtual server %s" %
-                                (time.asctime(time.gmtime()), self.name))
-                # execute each init script in turn
-                # XXX - we don't support all scripts that vserver script does
-                self.__do_chcontext(state_file)
-                for cmd in self.INITSCRIPTS:
-                    try:
-                        # enter vserver context
-                        arg_subst = { 'runlevel': runlevel }
-                        cmd_args = [cmd[0]] + map(lambda x: x % arg_subst,
-                                                   cmd[1:])
-                        if os.path.isfile(cmd[0]):                         
-                            print >>log, "executing '%s'" % " ".join(cmd_args)
-                            os.spawnvp(os.P_NOWAIT,cmd[0],cmd_args)
-                        else:
-                            print >>log, "WARNING: could not run %s"%cmd[0]
-                    except:
-                        print >>log, traceback.format_exc()
-
-            # we get here due to an exception in the top-level child process
+            # we get here due to an exception in the grandson process
             except Exception, ex:
                 self.log(traceback.format_exc())
             os._exit(0)
 
+
     def set_resources(self,setup=False):
 
         """ Called when vserver context is entered for first time,