X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fplanetlab.c;h=879cb5d8967a9acb8a2d1d49ed742959743f83dc;hb=refs%2Fheads%2Fplanetlab-3_2-branch;hp=6b5d936450f7983b937b3317660af47490b3258c;hpb=c7bb554b8d855b318f2699788c99c9e0402d893e;p=util-vserver.git diff --git a/lib/planetlab.c b/lib/planetlab.c index 6b5d936..879cb5d 100644 --- a/lib/planetlab.c +++ b/lib/planetlab.c @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include @@ -49,11 +50,14 @@ create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) struct vc_ctx_flags vc_flags; struct vc_rlimit vc_rlimit; - /* create context info */ + /* + * Create context info - this sets the STATE_SETUP and STATE_INIT flags. + * Don't ever clear the STATE_INIT flag, that makes us the init task. + */ if (vc_ctx_create(ctx) == VC_NOCTX) return -1; - /* set capabilities - these don't take effect until SETUP flags is unset */ + /* set capabilities - these don't take effect until SETUP flag is unset */ vc_caps.bcaps = bcaps; vc_caps.bmask = ~0ULL; /* currently unused */ vc_caps.ccaps = 0; /* don't want any of these */ @@ -61,14 +65,9 @@ create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) if (vc_set_ccaps(ctx, &vc_caps)) return -1; - /* ignore all flags except SETUP and scheduler flags */ - vc_flags.mask = VC_VXF_STATE_SETUP | VC_VXF_SCHED_FLAGS; - /* don't let user change scheduler flags */ - vc_flags.flagword = flags & ~VC_VXF_SCHED_FLAGS; /* SETUP not set */ - /* set scheduler parameters */ - vc_flags.flagword |= rspec->cpu_sched_flags; - pl_setsched(ctx, rspec->cpu_share, rspec->cpu_sched_flags); + if (pl_setsched(ctx, rspec->cpu_share, rspec->cpu_sched_flags)) + return -1; /* set resource limits */ vc_rlimit.min = VC_LIM_KEEP; @@ -83,6 +82,9 @@ create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) return -1; /* set flags, unset SETUP flag - this allows other processes to migrate */ + vc_flags.mask = VC_VXF_STATE_SETUP | VC_VXF_SCHED_FLAGS; + flags = 0; /* XXX - ignore flags parameter */ + vc_flags.flagword = flags | rspec->cpu_sched_flags; /* SETUP cleared */ if (vc_set_cflags(ctx, &vc_flags)) return -1; @@ -133,10 +135,27 @@ pl_chcontext(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) return 0; } +/* it's okay for a syscall to fail because the context doesn't exist */ +#define VC_SYSCALL(x) \ +do \ +{ \ + if (x) \ + return errno == ESRCH ? 0 : -1; \ +} \ +while (0) + + int pl_setsched(xid_t ctx, uint32_t cpu_share, uint32_t cpu_sched_flags) { struct vc_set_sched vc_sched; + struct vc_ctx_flags vc_flags; + + if (cpu_sched_flags & ~VC_VXF_SCHED_FLAGS) + { + errno = EINVAL; + return -1; + } vc_sched.set_mask = (VC_VXSM_FILL_RATE | VC_VXSM_INTERVAL | VC_VXSM_TOKENS | VC_VXSM_TOKENS_MIN | VC_VXSM_TOKENS_MAX); @@ -146,5 +165,18 @@ pl_setsched(xid_t ctx, uint32_t cpu_share, uint32_t cpu_sched_flags) vc_sched.tokens_min = 50; /* need this many tokens to run */ vc_sched.tokens_max = 100; /* max accumulated number of tokens */ - return vc_set_sched(ctx, &vc_sched); + VC_SYSCALL(vc_set_sched(ctx, &vc_sched)); + + /* get current flag values */ + VC_SYSCALL(vc_get_cflags(ctx, &vc_flags)); + + /* the only flag which ever changes is the SCHED_SHARE bit */ + if ((vc_flags.flagword ^ cpu_sched_flags) & VC_VXF_SCHED_SHARE) + { + vc_flags.mask = VC_VXF_SCHED_SHARE; + vc_flags.flagword = cpu_sched_flags & VC_VXF_SCHED_FLAGS; + VC_SYSCALL(vc_set_cflags(ctx, &vc_flags)); + } + + return 0; }