+ if (not args.pidns):
+ setns.chcontext('/proc/%s/ns/pid'%pid)
+
+ if (not args.netns):
+ setns.chcontext('/proc/%s/ns/net'%pid)
+
+ if (not args.mntns):
+ setns.chcontext('/proc/%s/ns/mnt'%pid)
+
+ proc_mounted = False
+ if (not os.access('/proc/self',0)):
+ proc_mounted = True
+ setns.proc_mount()
+
+ for (sysctl_file, sysctl_name, sysctl_val) in sysctls:
+ for fn in ["/sbin/sysctl", "/usr/sbin/sysctl", "/bin/sysctl", "/usr/bin/sysctl"]:
+ if os.path.exists(fn):
+ os.system('%s -w %s=%s'%(fn, sysctl_name,sysctl_val))
+ break
+ else:
+ print "Error: image does not have a sysctl binary"
+
+ # cgroups is not yet LXC-safe, so we need to use the coarse grained access control
+ # strategy of unmounting the filesystem
+
+ umount_result = True
+ for subsystem in ['cpuset','cpu,cpuacct','memory','devices','freezer','net_cls','blkio','perf_event']:
+ fs_path = '/sys/fs/cgroup/%s'%subsystem
+ if (not umount(fs_path)):
+ print "Error disabling cgroup access"
+ exit(1)
+
+ if (not umount('/sys/fs/cgroup')):
+ print "Error disabling cgroup access"
+ exit(1)
+
+ pid = os.fork()
+
+ # capsh has a --user option starting with f14
+ # so if only for f12 we need to fake this one
+ #
+ # capsh.c does essentially the following when invoked with --user:
+ # pwd = getpwnam(user); ...
+ # ngroups = MAX_GROUPS;
+ # status = getgrouplist(user, pwd->pw_gid, groups, &ngroups); ...
+ # status = setgroups(ngroups, groups); ...
+ # status = setgid(pwd->pw_gid); ...
+ # status = setuid(pwd->pw_uid); ...
+ # however we cannot simulate that ourselves because if we did in this process then
+ # capsh could not be allowed to mess with caps any more
+
+ def getuid (slicename):
+ import pwd
+ try:
+ return pwd.getpwnam(slicename).pw_uid
+ except:
+ return
+
+ if (pid == 0):
+ cap_arg = '--drop='+drop_capabilities
+
+ if (not args.root):
+ if (args.nosliceuid):
+ # we still want to drop capabilities, but don't want to switch UIDs
+ exec_args = [arch,'/usr/sbin/capsh',cap_arg,'--','--login',]+args.command_to_run
+ else:
+ uid = getuid (slice_name)
+ if not uid:
+ print "lxcsu could not spot %s in /etc/passwd - exiting"%slice_name
+ exit(1)
+ exec_args = [arch,'/usr/sbin/capsh',cap_arg,'--uid=%s'%uid,'--','--login',]+args.command_to_run
+# once we can drop f12, it would be nicer to instead go for
+# exec_args = [arch,'/usr/sbin/capsh',cap_arg,'--user=%s'%slice_name,'--','--login',]+args.command_to_run
+ else:
+ exec_args = [arch,'/usr/sbin/capsh','--','--login']+args.command_to_run
+
+ os.environ['SHELL'] = '/bin/sh'
+ os.environ['HOME'] = '/home/%s'%slice_name
+ if os.path.exists('/etc/planetlab/lib/bind_public.so'):
+ os.environ['LD_PRELOAD'] = '/etc/planetlab/lib/bind_public.so'
+ os.chdir("/home/%s"%(slice_name))
+ if debug: print 'lxcsu:execv:','/usr/bin/setarch',exec_args
+ os.execv('/usr/bin/setarch',exec_args)
+ else:
+ setns.proc_umount()
+ _,status = os.waitpid(pid,0)
+ exit(os.WEXITSTATUS(status))
+
+if __name__ == '__main__':
+ main()