X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fvserver.py;h=a4e828d00111901cd04066e0e6e833243e077afd;hb=16d8f5d34df3c1fd2f3895fae64e1b77a5c8e6b1;hp=55d78f044209ec79104fb79ed75c787c501cec36;hpb=a6e1134d8bdb41b0146cdac83e4e82909e74cb47;p=util-vserver-pl.git diff --git a/python/vserver.py b/python/vserver.py index 55d78f0..a4e828d 100644 --- a/python/vserver.py +++ b/python/vserver.py @@ -20,6 +20,7 @@ import cpulimit, bwlimit from vserverimpl import DLIMIT_INF from vserverimpl import VC_LIM_KEEP +from vserverimpl import VC_LIM_INFINITY from vserverimpl import VLIMIT_NSOCK from vserverimpl import VLIMIT_OPENFD from vserverimpl import VLIMIT_ANON @@ -133,9 +134,6 @@ class VServerConfig: 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 @@ -154,12 +152,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) @@ -228,18 +230,25 @@ class VServer: def set_ipaddresses(self, addresses): vserverimpl.netremove(self.ctx, "all") - for a in addresses.split(","): - vserverimpl.netadd(self.ctx, a) + for ip in addresses: + vserverimpl.netadd(self.ctx, ip) def set_ipaddresses_config(self, addresses): - return # acb + ip_addresses = addresses.split(",") + + # add looopback interface + if not ip_addresses.__contains__("127.0.0.1"): + ip_addresses.append("127.0.0.1") + i = 0 - for a in addresses.split(","): - self.config.update("interfaces/%d/ip" % i, a) + for ip in ip_addresses: + self.config.update("interfaces/%d/ip" % i, ip) + # create emtpy nodev files to silent "No device specified for" warnings + self.config.update("interfaces/%d/nodev" % i, "") i += 1 - while self.config.unset("interfaces/%d/ip" % i): + while self.config.unset("interfaces/%d/ip" % i) and self.config.update("interfaces/%d/nodev" % i): i += 1 - self.set_ipaddresses(addresses) + self.set_ipaddresses(ip_addresses) def get_ipaddresses_config(self): i = 0 @@ -261,13 +270,13 @@ 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(".") @@ -326,7 +335,7 @@ class VServer: def set_sched_config(self, cpu_min, cpu_share): """ Write current CPU scheduler parameters to the vserver configuration file. Currently, 'cpu_min' is not supported. """ - self.config.update('cgroup/cpu.shares', cpu_share * CPU_SHARE_MULT) + self.config.update('cgroup/cpu.shares', int(cpu_share) * CPU_SHARE_MULT) if self.is_running(): self.set_sched(cpu_min, cpu_share) @@ -334,8 +343,8 @@ class VServer: """ Update kernel CPU scheduling parameters for this context. Currently, 'cpu_min' is not supported. """ try: - cgroup = open('/dev/cgroup/%s/cpu.shares' % name, 'w') - cgroup.write('%s' % (cpu_share * CPU_SHARE_MULT)) + cgroup = open('/dev/cgroup/%s/cpu.shares' % self.name, 'w') + cgroup.write('%s' % (int(cpu_share) * CPU_SHARE_MULT)) cgroup.close() except: pass @@ -372,17 +381,28 @@ class VServer: def enter(self): subprocess.call("/usr/sbin/vserver %s enter" % self.name, shell=True) + # 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(0022) try: - subprocess.call("/usr/sbin/vserver %s start" % self.name, - shell=True) - # we get here due to an exception in the top-level child process + # start the vserver + subprocess.call(["/usr/sbin/vserver",self.name,"start"]) + + # we get here due to an exception in the grandson process except Exception, ex: self.log(traceback.format_exc()) os._exit(0) @@ -448,12 +468,3 @@ 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 -