X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fplanetlab.c;h=a41294019dfbede4fde17bc3a477f009a53c926d;hb=91f3bf94636e7e3127c031640d8a51977045582f;hp=e8d8120be1a1af2ab22029e2701b2880c422d2b6;hpb=36499d4016b36a5e7bc3d64efd3478cbb17133ec;p=util-vserver.git diff --git a/lib/planetlab.c b/lib/planetlab.c index e8d8120..a412940 100644 --- a/lib/planetlab.c +++ b/lib/planetlab.c @@ -31,6 +31,9 @@ POSSIBILITY OF SUCH DAMAGE. */ +#ifdef HAVE_CONFIG_H +# include +#endif #include #include #include @@ -40,28 +43,38 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include -#include "config.h" -#include "sched_cmd.h" -#include "virtual.h" #include "vserver.h" #include "planetlab.h" static int -create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, struct sliver_resources *slr) +create_context(xid_t ctx, uint64_t bcaps, struct sliver_resources *slr) { struct vc_ctx_caps vc_caps; + struct vc_net_nx vc_net; + struct vc_net_flags vc_nf; + + /* Create network context */ + if (vc_net_create(ctx) == VC_NOCTX) { + if (errno == EEXIST) + goto process; + return -1; + } + /* Make the network context persistent */ + vc_nf.mask = vc_nf.flagword = VC_NXF_PERSISTENT; + if (vc_set_nflags(ctx, &vc_nf)) + return -1; + +process: /* * 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. - * - * XXX - the kernel code allows initial flags to be passed as an arg. */ if (vc_ctx_create(ctx) == VC_NOCTX) return -1; - /* set capabilities - these don't take effect until SETUP flag 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 */ @@ -80,8 +93,10 @@ pl_setup_done(xid_t ctx) struct vc_ctx_flags vc_flags; /* unset SETUP flag - this allows other processes to migrate */ - vc_flags.mask = VC_VXF_STATE_SETUP; - vc_flags.flagword = 0; + /* set the PERSISTENT flag - so the context doesn't vanish */ + /* Don't clear the STATE_INIT flag, as that would make us the init task. */ + vc_flags.mask = VC_VXF_STATE_SETUP|VC_VXF_PERSISTENT; + vc_flags.flagword = VC_VXF_PERSISTENT; if (vc_set_cflags(ctx, &vc_flags)) return -1; @@ -91,9 +106,10 @@ pl_setup_done(xid_t ctx) #define RETRY_LIMIT 10 int -pl_chcontext(xid_t ctx, uint32_t flags, uint64_t bcaps, struct sliver_resources *slr) +pl_chcontext(xid_t ctx, uint64_t bcaps, struct sliver_resources *slr) { int retry_count = 0; + int net_migrated = 0; for (;;) { @@ -105,7 +121,7 @@ pl_chcontext(xid_t ctx, uint32_t flags, uint64_t bcaps, struct sliver_resources return -1; /* context doesn't exist - create it */ - if (create_context(ctx, flags, bcaps,slr)) + if (create_context(ctx, bcaps, slr)) { if (errno == EEXIST) /* another process beat us in a race */ @@ -135,8 +151,12 @@ pl_chcontext(xid_t ctx, uint32_t flags, uint64_t bcaps, struct sliver_resources /* context has been setup */ migrate: - if (!vc_ctx_migrate(ctx)) - break; /* done */ + if (net_migrated || !vc_net_migrate(ctx)) + { + if (!vc_ctx_migrate(ctx, 0)) + break; /* done */ + net_migrated = 1; + } /* context disappeared - retry */ } @@ -161,28 +181,32 @@ pl_setsched(xid_t ctx, uint32_t cpu_share, uint32_t cpu_sched_flags) uint32_t new_flags; vc_sched.set_mask = (VC_VXSM_FILL_RATE | VC_VXSM_INTERVAL | VC_VXSM_TOKENS | - VC_VXSM_TOKENS_MIN | VC_VXSM_TOKENS_MAX); - vc_sched.fill_rate = cpu_share; /* tokens accumulated per interval */ - vc_sched.interval = 1000; /* milliseconds */ + VC_VXSM_TOKENS_MIN | VC_VXSM_TOKENS_MAX | VC_VXSM_MSEC | + VC_VXSM_FILL_RATE2 | VC_VXSM_INTERVAL2 | VC_VXSM_FORCE | + VC_VXSM_IDLE_TIME); + vc_sched.fill_rate = 0; + vc_sched.fill_rate2 = cpu_share; /* tokens accumulated per interval */ + vc_sched.interval = vc_sched.interval2 = 1000; /* milliseconds */ vc_sched.tokens = 100; /* initial allocation of tokens */ vc_sched.tokens_min = 50; /* need this many tokens to run */ vc_sched.tokens_max = 100; /* max accumulated number of tokens */ - VC_SYSCALL(vc_set_sched(ctx, &vc_sched)); - - /* get current flag values */ - VC_SYSCALL(vc_get_cflags(ctx, &vc_flags)); + if (cpu_share == (uint32_t)VC_LIM_KEEP) + vc_sched.set_mask &= ~(VC_VXSM_FILL_RATE|VC_VXSM_FILL_RATE2); /* guaranteed CPU corresponds to SCHED_SHARE flag being cleared */ - new_flags = (cpu_sched_flags & VS_SCHED_CPU_GUARANTEED - ? 0 - : VC_VXF_SCHED_SHARE); - if ((vc_flags.flagword & VC_VXF_SCHED_SHARE) != new_flags) - { - vc_flags.mask = VC_VXF_SCHED_FLAGS; - vc_flags.flagword = new_flags | VC_VXF_SCHED_HARD; - VC_SYSCALL(vc_set_cflags(ctx, &vc_flags)); - } + if (cpu_sched_flags & VS_SCHED_CPU_GUARANTEED) { + new_flags = 0; + vc_sched.fill_rate = vc_sched.fill_rate2; + } + else + new_flags = VC_VXF_SCHED_SHARE; + + VC_SYSCALL(vc_set_sched(ctx, &vc_sched)); + + vc_flags.mask = VC_VXF_SCHED_FLAGS; + vc_flags.flagword = new_flags | VC_VXF_SCHED_HARD; + VC_SYSCALL(vc_set_cflags(ctx, &vc_flags)); return 0; } @@ -201,37 +225,37 @@ void pl_get_limits(char *context, struct sliver_resources *slr) { FILE *fb; - size_t len = strlen(VSERVERCONF) + strlen(context) + strlen(".conf") + NULLBYTE_SIZE; - char *conf = (char *)malloc(len); + int cwd; + size_t len = strlen(VSERVERCONF) + strlen(context) + NULLBYTE_SIZE; + char *conf = (char *)malloc(len + strlen("rlimits/openfd.hard")); struct pl_resources *r; struct pl_resources sliver_list[] = { - {"CPULIMIT", &slr->vs_cpu}, - {"CPUSHARE", &slr->vs_cpu}, - {"CPUGUARANTEED", &slr->vs_cpuguaranteed}, + {"sched/fill-rate2", &slr->vs_cpu}, + {"sched/fill-rate", &slr->vs_cpuguaranteed}, - {"TASKLIMIT", &slr->vs_nproc.hard}, /* backwards compatible */ - {"VS_NPROC_HARD", &slr->vs_nproc.hard}, - {"VS_NPROC_SOFT", &slr->vs_nproc.soft}, - {"VS_NPROC_MINIMUM", &slr->vs_nproc.min}, + {"rlimits/nproc.hard", &slr->vs_nproc.hard}, + {"rlimits/nproc.soft", &slr->vs_nproc.soft}, + {"rlimits/nproc.min", &slr->vs_nproc.min}, - {"MEMLIMIT", &slr->vs_rss.hard}, /* backwards compatible */ - {"VS_RSS_HARD", &slr->vs_rss.hard}, - {"VS_RSS_SOFT", &slr->vs_rss.soft}, - {"VS_RSS_MINIMUM", &slr->vs_rss.min}, + {"rlimits/rss.hard", &slr->vs_rss.hard}, + {"rlimits/rss.soft", &slr->vs_rss.soft}, + {"rlimits/rss.min", &slr->vs_rss.min}, - {"VS_AS_HARD", &slr->vs_as.hard}, - {"VS_AS_SOFT", &slr->vs_as.soft}, - {"VS_AS_MINIMUM", &slr->vs_as.min}, + {"rlimits/as.hard", &slr->vs_as.hard}, + {"rlimits/as.soft", &slr->vs_as.soft}, + {"rlimits/as.min", &slr->vs_as.min}, - {"VS_OPENFD_HARD", &slr->vs_openfd.hard}, - {"VS_OPENFD_SOFT", &slr->vs_openfd.soft}, - {"VS_OPENFD_MINIMUM", &slr->vs_openfd.min}, + {"rlimits/openfd.hard", &slr->vs_openfd.hard}, + {"rlimits/openfd.soft", &slr->vs_openfd.soft}, + {"rlimits/openfd.min", &slr->vs_openfd.min}, + + {"whitelisted", &slr->vs_whitelisted}, - {"VS_WHITELISTED", &slr->vs_whitelisted}, + {"bcapabilities", NULL}, {0,0} }; - sprintf(conf, "%s%s.conf", VSERVERCONF, context); + sprintf(conf, "%s%s", VSERVERCONF, context); slr->vs_cpu = VC_LIM_KEEP; slr->vs_cpuguaranteed = 0; @@ -255,55 +279,53 @@ pl_get_limits(char *context, struct sliver_resources *slr) slr->vs_whitelisted = 1; - /* open the conf file for reading */ - fb = fopen(conf,"r"); - if (fb != NULL) { - size_t index; - char *buffer = malloc(1000); - char *p; - - /* the conf file exist */ - while((p=fgets(buffer,1000-1,fb))!=NULL) { - index = 0; - len = strnlen(buffer,1000); - WHITESPACE(buffer,index,len); - if (buffer[index] == '#') - continue; - - for (r=&sliver_list[0]; r->name; r++) - if ((p=strstr(&buffer[index],r->name))!=NULL) { - /* adjust index into buffer */ - index+= (p-&buffer[index])+strlen(r->name); - - /* skip over whitespace */ - WHITESPACE(buffer,index,len); - - /* expecting to see = sign */ - if (buffer[index++]!='=') goto out; - - /* skip over whitespace */ - WHITESPACE(buffer,index,len); - - /* expecting to see a digit for number */ - if (!isdigit((int)buffer[index])) goto out; - - *r->limit = atoi(&buffer[index]); - if (0) /* for debugging only */ - fprintf(stderr,"pl_get_limits found %s=%ld\n", - r->name,*r->limit); - break; - } + slr->vs_capabilities.bcaps = 0; + slr->vs_capabilities.bmask = 0; + slr->vs_capabilities.ccaps = 0; + slr->vs_capabilities.cmask = 0; + + cwd = open(".", O_RDONLY); + if (cwd == -1) { + perror("cannot get a handle on ."); + goto out; + } + if (chdir(conf) == -1) { + fprintf(stderr, "cannot chdir to "); + perror(conf); + goto out_fd; + } + + for (r = &sliver_list[0]; r->name; r++) { + char buf[1000]; + fb = fopen(r->name, "r"); + if (fb == NULL) + continue; + /* XXX: UGLY. */ + if (strcmp(r->name, "bcapabilities") == 0) { + size_t len, i; + struct vc_err_listparser err; + + len = fread(buf, 1, sizeof(buf), fb); + for (i = 0; i < len; i++) { + if (buf[i] == '\n') + buf[i] = ','; + } + vc_list2bcap(buf, len, &err, &slr->vs_capabilities); } - out: + else + if (fgets(buf, sizeof(buf), fb) != NULL && isdigit(*buf)) + *r->limit = atoi(buf); fclose(fb); - free(buffer); - } else { - fprintf(stderr,"cannot open %s\n",conf); } + + fchdir(cwd); +out_fd: + close(cwd); +out: free(conf); } -static inline int +int adjust_lim(struct vc_rlimit *vcr, struct rlimit *lim) { int adjusted = 0; @@ -342,7 +364,6 @@ adjust_lim(struct vc_rlimit *vcr, struct rlimit *lim) return adjusted; } - void pl_set_limits(xid_t ctx, struct sliver_resources *slr) { @@ -392,11 +413,7 @@ pl_set_limits(xid_t ctx, struct sliver_resources *slr) PERROR("pl_setrlimit(%u, RLIMIT_NOFILE)", ctx); exit(1); } -#ifndef VLIMIT_OPENFD -#warning VLIMIT_OPENFD should be defined from standard header -#define VLIMIT_OPENFD 17 -#endif - if (vc_set_rlimit(ctx, VLIMIT_OPENFD, &slr->vs_openfd)) + if (vc_set_rlimit(ctx, VC_VLIMIT_OPENFD, &slr->vs_openfd)) { PERROR("pl_setrlimit(%u, VLIMIT_OPENFD)", ctx); exit(1); @@ -404,13 +421,19 @@ pl_set_limits(xid_t ctx, struct sliver_resources *slr) } vs_cpu = slr->vs_cpu; cpu_sched_flags = slr->vs_cpuguaranteed & VS_SCHED_CPU_GUARANTEED; + + slr->vs_capabilities.bmask = vc_get_insecurebcaps(); + if (vc_set_ccaps(ctx, &slr->vs_capabilities) < 0) { + PERROR("pl_setcaps(%u)", ctx); + exit(1); + } } else { vs_cpu = 1; cpu_sched_flags = 0; } if (pl_setsched(ctx, vs_cpu, cpu_sched_flags) < 0) { - PERROR("pl_setsched(&u)", ctx); + PERROR("pl_setsched(%u)", ctx); exit(1); } }