Don't clean stuff up if it's already running.
[util-vserver-pl.git] / python / vserver.py
index 577a44a..aee6d03 100644 (file)
@@ -129,6 +129,26 @@ class VServerConfig:
         os.path.walk(self.dir, add_to_cache, self.cache)
 
 
+def adjust_lim(goal, curr):
+    gh = goal[0]
+    gs = goal[1]
+    gm = goal[2]
+    soft = curr[0]
+    hard = curr[1]
+    if gm != VC_LIM_KEEP:
+        if gm > soft or gm == resource.RLIM_INFINITY:
+            soft = gm
+        if gm > hard or gm == resource.RLIM_INFINITY:
+            hard = gm
+    if gs != VC_LIM_KEEP:
+        if gs > soft or gs == resource.RLIM_INFINITY:
+            soft = gs
+    if gh != VC_LIM_KEEP:
+        if gh > hard or gh == resource.RLIM_INFINITY:
+            hard = gh
+    return (soft, hard)
+
+
 class VServer:
 
     INITSCRIPTS = [('/etc/rc.vinit', 'start'),
@@ -181,6 +201,10 @@ class VServer:
             resource_type = RLIMITS[type]
             try:
                 vserverimpl.setrlimit(self.ctx, resource_type, hard, soft, min)
+                if hasattr(resource, 'RLIMIT_' + type):
+                    lim = resource.getrlimit(resource_type)
+                    lim = adjust_lim((hard, soft, min), lim)
+                    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))
@@ -277,7 +301,7 @@ class VServer:
             try:
                 vserverimpl.unsetdlimit(self.dir, self.ctx)
             except OSError, e:
-                self.log("Unexpected error with unsetdlimit for context %d" % self.ctx)
+                self.log("Unexpected error with unsetdlimit for context %d: %r" % (self.ctx,e))
             return
 
         if self.vm_running:
@@ -297,7 +321,7 @@ class VServer:
                                   vserverimpl.DLIMIT_INF,  # inode limit
                                   2)   # %age reserved for root
         except OSError, e:
-            self.log("Unexpected error with setdlimit for context %d" % self.ctx)
+            self.log("Unexpected error with setdlimit for context %d: %r" % (self.ctx, e))
 
 
         self.config.update('dlimits/0/space_total', block_limit)
@@ -372,37 +396,44 @@ class VServer:
             self.set_resources(True)
             vserverimpl.setup_done(self.ctx)
 
+
     def __prep(self, runlevel):
 
         """ Perform all the crap that the vserver script does before
         actually executing the startup scripts. """
 
-        # remove /var/run and /var/lock/subsys files
-        # but don't remove utmp from the top-level /var/run
-        RUNDIR = "/var/run"
-        LOCKDIR = "/var/lock/subsys"
-        filter_fn = lambda fs: filter(lambda f: f != 'utmp', fs)
-        garbage = reduce((lambda (out, ff), (dir, subdirs, files):
-                          (out + map((dir + "/").__add__, ff(files)),
-                           lambda fs: fs)),
-                         list(os.walk(RUNDIR)),
-                         ([], filter_fn))[0]
-        garbage += filter(os.path.isfile, map((LOCKDIR + "/").__add__,
-                                              os.listdir(LOCKDIR)))
-        if False:
-            for f in garbage:
-                os.unlink(f)
 
         # set the initial runlevel
-        vserverimpl.setrunlevel(RUNDIR + "/utmp", runlevel)
+        vserverimpl.setrunlevel(self.dir + "/var/run/utmp", runlevel)
 
         # mount /proc and /dev/pts
         self.__do_mount("none", self.dir, "/proc", "proc")
         # XXX - magic mount options
         self.__do_mount("none", self.dir, "/dev/pts", "devpts", 0, "gid=5,mode=0620")
 
-    def __do_mount(self, *mount_args):
 
+    def __cleanvar(self):
+        """
+        Clean the /var/ directory so RH startup scripts can run
+        """ 
+
+        RUNDIR = "/var/run"
+        LOCKDIR = "/var/lock/subsys"
+
+        filter = ["utmp"]
+        garbage = []
+        for topdir in [RUNDIR, LOCKDIR]:
+            #os.walk() = (dirpath, dirnames, filenames)
+            for root, dirs, files in os.walk(topdir):
+                for file in files:
+                    if not file in filter:
+                        garbage.append(root + "/" + file)
+
+        for f in garbage: os.unlink(f)
+        return garbage
+
+
+    def __do_mount(self, *mount_args):
         try:
             vserverimpl.mount(*mount_args)
         except OSError, ex:
@@ -411,11 +442,13 @@ class VServer:
                 return
             raise ex
 
+
     def enter(self):
         self.config.cache_it()
         self.__do_chroot()
         self.__do_chcontext(None)
 
+
     def start(self, runlevel = 3):
 
         if (os.fork() != 0):
@@ -434,7 +467,7 @@ class VServer:
                 # 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
+                # use /dev/null for stdin, /var/log/nm for stdout/err
                 fd = os.open("/dev/null", os.O_RDONLY)
                 if fd != 0:
                     os.dup2(fd, 0)
@@ -445,13 +478,18 @@ class VServer:
 
                 self.config.cache_it()
                 self.__do_chroot()
-                log = open("/var/log/boot.log", "a", 0)
+                if not self.is_running():
+                    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))
+                                (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)
@@ -464,6 +502,8 @@ class VServer:
                         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()