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 (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;
- /* XXX: Allow access to all IPv4 addresses (for now) */
- vc_net.type = vcNET_IPV4;
- vc_net.count = 1;
- vc_net.ip[0] = 0;
- vc_net.mask[0] = 0;
- if (vc_net_add(ctx, &vc_net) == -1)
- return -1;
-
+process:
/*
* Create context info - this sets the STATE_SETUP and STATE_INIT flags.
*/
int retry_count = 0;
int net_migrated = 0;
+ pl_set_ulimits(slr);
+
for (;;)
{
struct vc_ctx_flags vc_flags;
return -1;
/* context doesn't exist - create it */
- if (create_context(ctx, bcaps,slr))
+ if (create_context(ctx, bcaps, slr))
{
if (errno == EEXIST)
/* another process beat us in a race */
vc_sched.tokens_min = 50; /* need this many tokens to run */
vc_sched.tokens_max = 100; /* max accumulated number of tokens */
- if (cpu_share == VC_LIM_KEEP)
+ if (cpu_share == (uint32_t)VC_LIM_KEEP)
vc_sched.set_mask &= ~(VC_VXSM_FILL_RATE|VC_VXSM_FILL_RATE2);
- VC_SYSCALL(vc_set_sched(ctx, &vc_sched));
-
- /* get current flag values */
- VC_SYSCALL(vc_get_cflags(ctx, &vc_flags));
-
/* guaranteed CPU corresponds to SCHED_SHARE flag being cleared */
if (cpu_sched_flags & VS_SCHED_CPU_GUARANTEED) {
- new_flags = VC_VXF_SCHED_SHARE;
+ new_flags = 0;
vc_sched.fill_rate = vc_sched.fill_rate2;
}
else
- new_flags = 0;
+ new_flags = 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));
- }
+ 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;
}
{"rlimits/openfd.soft", &slr->vs_openfd.soft},
{"rlimits/openfd.min", &slr->vs_openfd.min},
- {"whitelisted", &slr->vs_whitelisted},
+ {"bcapabilities", NULL},
{0,0}
};
slr->vs_openfd.soft = VC_LIM_KEEP;
slr->vs_openfd.min = VC_LIM_KEEP;
- slr->vs_whitelisted = 1;
+ 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) {
fb = fopen(r->name, "r");
if (fb == NULL)
continue;
- if (fgets(buf, sizeof(buf), fb) != NULL && isdigit(*buf)) {
- *r->limit = atoi(buf);
+ /* 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);
}
+ else
+ if (fgets(buf, sizeof(buf), fb) != NULL && isdigit(*buf))
+ *r->limit = atoi(buf);
fclose(fb);
}
out_fd:
close(cwd);
out:
-#if 0
- /* 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=%lld\n",
- r->name,*r->limit);
- break;
- }
- }
- out:
- fclose(fb);
- free(buffer);
- } else {
- fprintf(stderr,"cannot open %s\n",conf);
- }
-#endif
free(conf);
}
return adjusted;
}
+static inline void
+set_one_ulimit(int resource, struct vc_rlimit *limit)
+{
+ struct rlimit lim;
+ getrlimit(resource, &lim);
+ adjust_lim(limit, &lim);
+ setrlimit(resource, &lim);
+}
+
+void
+pl_set_ulimits(struct sliver_resources *slr)
+{
+ if (!slr)
+ return;
+
+ set_one_ulimit(RLIMIT_RSS, &slr->vs_rss);
+ set_one_ulimit(RLIMIT_AS, &slr->vs_as);
+ set_one_ulimit(RLIMIT_NPROC, &slr->vs_nproc);
+ set_one_ulimit(RLIMIT_NOFILE, &slr->vs_openfd);
+}
void
pl_set_limits(xid_t ctx, struct sliver_resources *slr)
{
- struct rlimit lim; /* getrlimit values */
unsigned long long vs_cpu;
uint32_t cpu_sched_flags;
if (slr != 0) {
/* set memory limits */
- getrlimit(RLIMIT_RSS,&lim);
- if (adjust_lim(&slr->vs_rss, &lim)) {
- setrlimit(RLIMIT_RSS, &lim);
- if (vc_set_rlimit(ctx, RLIMIT_RSS, &slr->vs_rss))
- {
- PERROR("pl_setrlimit(%u, RLIMIT_RSS)", ctx);
- exit(1);
- }
+ if (vc_set_rlimit(ctx, RLIMIT_RSS, &slr->vs_rss)) {
+ PERROR("pl_setrlimit(%u, RLIMIT_RSS)", ctx);
+ exit(1);
}
/* set address space limits */
- getrlimit(RLIMIT_AS,&lim);
- if (adjust_lim(&slr->vs_as, &lim)) {
- setrlimit(RLIMIT_AS, &lim);
- if (vc_set_rlimit(ctx, RLIMIT_AS, &slr->vs_as))
- {
- PERROR("pl_setrlimit(%u, RLIMIT_AS)", ctx);
- exit(1);
- }
+ if (vc_set_rlimit(ctx, RLIMIT_AS, &slr->vs_as)) {
+ PERROR("pl_setrlimit(%u, RLIMIT_AS)", ctx);
+ exit(1);
}
+
/* set nrpoc limit */
- getrlimit(RLIMIT_NPROC,&lim);
- if (adjust_lim(&slr->vs_nproc, &lim)) {
- setrlimit(RLIMIT_NPROC, &lim);
- if (vc_set_rlimit(ctx, RLIMIT_NPROC, &slr->vs_nproc))
- {
- PERROR("pl_setrlimit(%u, RLIMIT_NPROC)", ctx);
- exit(1);
- }
+ if (vc_set_rlimit(ctx, RLIMIT_NPROC, &slr->vs_nproc)) {
+ PERROR("pl_setrlimit(%u, RLIMIT_NPROC)", ctx);
+ exit(1);
}
/* set openfd limit */
- getrlimit(RLIMIT_NOFILE,&lim);
- if (adjust_lim(&slr->vs_openfd, &lim)) {
- setrlimit(RLIMIT_NOFILE, &lim);
- if (vc_set_rlimit(ctx, RLIMIT_NOFILE, &slr->vs_openfd))
- {
- PERROR("pl_setrlimit(%u, RLIMIT_NOFILE)", ctx);
- exit(1);
- }
- if (vc_set_rlimit(ctx, VC_VLIMIT_OPENFD, &slr->vs_openfd))
- {
- PERROR("pl_setrlimit(%u, VLIMIT_OPENFD)", ctx);
- exit(1);
- }
+ if (vc_set_rlimit(ctx, RLIMIT_NOFILE, &slr->vs_openfd)) {
+ PERROR("pl_setrlimit(%u, RLIMIT_NOFILE)", ctx);
+ exit(1);
+ }
+ if (vc_set_rlimit(ctx, VC_VLIMIT_OPENFD, &slr->vs_openfd)) {
+ PERROR("pl_setrlimit(%u, VLIMIT_OPENFD)", ctx);
+ exit(1);
}
+
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);
}
}