Implement and use vserverimpl.setsched
[util-vserver.git] / python / vserver.py
index 325e2e2..9f1bb09 100644 (file)
@@ -28,11 +28,6 @@ FLAGS_HIDEINFO = 32
 FLAGS_ULIMIT = 64
 FLAGS_NAMESPACE = 128
 
-# default values for new vserver scheduler
-SCHED_TOKENS_MIN = 50
-SCHED_TOKENS_MAX = 100
-SCHED_TOKENS = 100
-SCHED_INTERVAL = 1000
 
               
 class VServer:
@@ -40,7 +35,7 @@ class VServer:
     INITSCRIPTS = [('/etc/rc.vinit', 'start'),
                    ('/etc/rc.d/rc', '%(runlevel)d')]
 
-    def __init__(self, name):
+    def __init__(self, name, vm_running = False, resources = {}):
 
         self.name = name
         self.config_file = "/etc/vservers/%s.conf" % name
@@ -58,6 +53,8 @@ class VServer:
             self.flags |= FLAGS_NPROC
         self.remove_caps = ~vserverimpl.CAP_SAFE;
         self.ctx = int(self.config["S_CONTEXT"])
+        self.vm_running = vm_running
+        self.resources = resources
 
     config_var_re = re.compile(r"^ *([A-Z_]+)=(.*)\n?$", re.MULTILINE)
 
@@ -84,7 +81,7 @@ class VServer:
             (key, val) = m.groups()
             newval = todo.pop(key, None)
             if newval != None:
-                data = data[:m.start(2)] + newval + data[m.end(2):]
+                data = data[:m.start(2)] + str(newval) + data[m.end(2):]
                 changed = True
         for (newkey, newval) in todo.items():
             data += "%s=%s\n" % (newkey, newval)
@@ -116,24 +113,21 @@ class VServer:
 
     def set_disklimit(self, block_limit):
 
-        # block_limit is in kB, get_disk_usage() must have been called
-        if self.disk_usage_set:
+        # block_limit is in kB
+        if self.vm_running:
             block_usage = vserverimpl.DLIMIT_KEEP
             inode_usage = vserverimpl.DLIMIT_KEEP
         else:
+            # init_disk_info() must have been called to get usage values
             block_usage = self.disk_blocks
             inode_usage = self.disk_inodes
-            if block_limit < block_usage:
-                raise Exception, ("%s disk usage (%u blocks) > limit (%u)" %
-                                  (self.name, block_usage, block_limit))
-            self.disk_usage_set = True
 
         vserverimpl.setdlimit(self.dir,
                               self.ctx,
                               block_usage,
                               block_limit,
                               inode_usage,
-                              -1,  # inode limit
+                              vserverimpl.DLIMIT_INF,  # inode limit
                               2)   # %age reserved for root
 
     def get_disklimit(self):
@@ -144,44 +138,18 @@ class VServer:
         except OSError, ex:
             if ex.errno == errno.ESRCH:
                 # get here if no vserver disk limit has been set for xid
-                # set blockused to -1 to indicate no limit
                 blocktotal = -1
 
         return blocktotal
 
-    def set_sched(self, shares = 32, besteffort = True):
-        # for the old CKRM scheduler
-        if cpulimit.checkckrm() is True:
-            cpulimit.cpuinit()
-            cpulimit.vs2ckrm_on(self.name)
-            try:
-                cpulimit.cpulimit(self.name,shares)
-            except OSError, ex:
-                if ex.errno == 22:
-                    print "invalid shares argument"
-                    # should re-raise exception?!
+    def set_sched(self, cpu_share):
 
-        # for the new vserver scheduler
-        else:
-            global SCHED_TOKENS_MIN, SCHED_TOKENS_MAX, SCHED_TOKENS, SCHED_INTERVAL
-            tokensmin = SCHED_TOKENS_MIN
-            tokensmax = SCHED_TOKENS_MAX
-            tokens    = SCHED_TOKENS
-            interval  = SCHED_INTERVAL
-            fillrate = shares
-
-            if besteffort is True:
-                cpuguaranteed = 0
-            else:
-                cpuguaranteed = 1
+        if cpu_share == int(self.config.get("CPULIMIT", -1)):
+            return
 
-            try:
-                vserverimpl.setsched(self.ctx,fillrate,interval,tokens,tokensmin,tokensmax,cpuguaranteed)
-            except OSError, ex:
-                if ex.errno == 22:
-                    print "kernel does not support vserver scheduler"
-                else:
-                    raise ex
+        self.__update_config_file(self.config_file, { "CPULIMIT": cpu_share })
+        if self.vm_running:
+            vserverimpl.setsched(self.ctx, self.resources)
 
     def get_sched(self):
         # have no way of querying scheduler right now on a per vserver basis
@@ -274,9 +242,9 @@ class VServer:
 
         return os.fdopen(fd, mode, bufsize)
 
-    def __do_chcontext(self, state_file = None):
+    def __do_chcontext(self, state_file):
 
-        vserverimpl.chcontext(self.ctx)
+        vserverimpl.chcontext(self.ctx, self.resources)
 
         if not state_file:
             return
@@ -332,8 +300,7 @@ class VServer:
 
     def start(self, wait, runlevel = 3):
 
-        # XXX - temporary hack
-        self.set_disklimit(int(self.config.get("DISKLIMIT", 5000000)))
+        self.vm_running = True
 
         child_pid = os.fork()
         if child_pid == 0:
@@ -411,19 +378,8 @@ class VServer:
         # write new values to configuration file
         self.__update_config_file(self.config_file, resources)
 
-        # disklimit can be applied without a process in context
-        disklimit = resources.get("DISKLIMIT", 0)
-        if disklimit:
-            self.set_disklimit(disklimit)
-
-        #
-        # Figure out if any processes are active in context, apply new
-        # values if there are.
-        #
-
     def init_disk_info(self):
 
         (self.disk_inodes, self.disk_blocks, size) = vduimpl.vdu(self.dir)
-        self.disk_usage_set = False
 
         return size