X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fvserver.py;h=577a44ae11429d0b16e92dcc44971c8f9909d308;hb=6b5db2f29ebe205319fc40f27a8cd745bfa29ff1;hp=e3748f4accfd4a845115680505058dbb52242d25;hpb=c691247edc297fa51265d333950b2004d8b357fc;p=util-vserver-pl.git diff --git a/python/vserver.py b/python/vserver.py index e3748f4..577a44a 100644 --- a/python/vserver.py +++ b/python/vserver.py @@ -187,18 +187,39 @@ class VServer: return update - def set_capabilities(self, capabilities): - return vserverimpl.setbcaps(self.ctx, vserverimpl.text2bcaps(capabilities)) + def get_prefix_from_capabilities(self, capabilities, prefix): + split_caps = capabilities.split(',') + return ",".join(["%s" % (c) for c in split_caps if c.startswith(prefix.upper()) or c.startswith(prefix.lower())]) + + def get_bcaps_from_capabilities(self, capabilities): + return self.get_prefix_from_capabilities(capabilities, "cap_") + + def get_ccaps_from_capabilities(self, capabilities): + return self.get_prefix_from_capabilities(capabilities, "vxc_") def set_capabilities_config(self, capabilities): - self.config.update('bcapabilities', capabilities) - self.set_capabilities(capabilities) + bcaps = self.get_bcaps_from_capabilities(capabilities) + ccaps = self.get_ccaps_from_capabilities(capabilities) + self.config.update('bcapabilities', bcaps) + self.config.update('ccapabilities', ccaps) + ret = vserverimpl.setbcaps(self.ctx, vserverimpl.text2bcaps(bcaps)) + if ret > 0: + return ret + return vserverimpl.setccaps(self.ctx, vserverimpl.text2ccaps(ccaps)) def get_capabilities(self): - return vserverimpl.bcaps2text(vserverimpl.getbcaps(self.ctx)) + bcaps = vserverimpl.bcaps2text(vserverimpl.getbcaps(self.ctx)) + ccaps = vserverimpl.ccaps2text(vserverimpl.getccaps(self.ctx)) + if bcaps and ccaps: + ccaps = "," + ccaps + return (bcaps + ccaps) def get_capabilities_config(self): - return self.config.get('bcapabilities', '') + bcaps = self.config.get('bcapabilities', '') + ccaps = self.config.get('ccapabilities', '') + if bcaps and ccaps: + ccaps = "," + ccaps + return (bcaps + ccaps) def set_ipaddresses(self, addresses): vserverimpl.netremove(self.ctx, "all") @@ -267,7 +288,6 @@ class VServer: block_usage = self.disk_blocks inode_usage = self.disk_inodes - try: vserverimpl.setdlimit(self.dir, self.ctx, @@ -349,7 +369,7 @@ class VServer: state_file.close() if vserverimpl.chcontext(self.ctx, vserverimpl.text2bcaps(self.get_capabilities_config())): - self.set_resources() + self.set_resources(True) vserverimpl.setup_done(self.ctx) def __prep(self, runlevel): @@ -396,13 +416,18 @@ class VServer: self.__do_chroot() self.__do_chcontext(None) - def start(self, wait, runlevel = 3): - self.vm_running = True + def start(self, runlevel = 3): - child_pid = os.fork() - if child_pid == 0: + if (os.fork() != 0): + # Parent should just return. + self.vm_running = True + return + else: # child process try: + # so we don't chcontext with priv'ed fds + close_nonstandard_fds() + # get a new session os.setsid() @@ -431,26 +456,23 @@ class VServer: # 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, + try: + # enter vserver context + arg_subst = { 'runlevel': runlevel } + cmd_args = [cmd[0]] + map(lambda x: x % arg_subst, cmd[1:]) - print >>log, "executing '%s'" % " ".join(cmd_args) - os.spawnvp(os.P_NOWAIT,cmd[0],cmd_args) - except: - print >>log, traceback.format_exc() - os._exit(1) + if os.path.isfile(cmd[0]): + print >>log, "executing '%s'" % " ".join(cmd_args) + os.spawnvp(os.P_NOWAIT,cmd[0],cmd_args) + except: + print >>log, traceback.format_exc() # we get here due to an exception in the top-level child process except Exception, ex: self.log(traceback.format_exc()) os._exit(0) - # parent process - return child_pid - - def set_resources(self): + def set_resources(self,setup=False): """ Called when vserver context is entered for first time, should be overridden by subclass. """ @@ -458,6 +480,13 @@ class VServer: pass def init_disk_info(self): + try: + dlimit = vserverimpl.getdlimit(self.dir, self.ctx) + self.disk_blocks = dlimit[0] + self.disk_inodes = dlimit[2] + return self.disk_blocks * 1024 + except Exception, e: + pass cmd = "/usr/sbin/vdu --script --space --inodes --blocksize 1024 --xid %d %s" % (self.ctx, self.dir) p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -506,3 +535,12 @@ def create(vm_name, static = False, ctor = VServer): vm_id = pwd.getpwnam(vm_name)[2] return ctor(vm_name, vm_id) + + +def close_nonstandard_fds(): + """Close all open file descriptors other than 0, 1, and 2.""" + _SC_OPEN_MAX = 4 + for fd in range(3, os.sysconf(_SC_OPEN_MAX)): + try: os.close(fd) + except OSError: pass # most likely an fd that isn't open +