+ return 0;
+}
+
+struct pl_resources {
+ char *name;
+ unsigned long long *limit;
+};
+
+#define WHITESPACE(buffer,index,len) \
+ while(isspace((int)buffer[index])) \
+ if (index < len) index++; else goto out;
+
+#define VSERVERCONF "/etc/vservers/"
+void
+pl_get_limits(const char *context, struct sliver_resources *slr)
+{
+ FILE *fb;
+ 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[] = {
+ {"sched/fill-rate2", &slr->vs_cpu},
+
+ {"rlimits/nproc.hard", &slr->vs_nproc.hard},
+ {"rlimits/nproc.soft", &slr->vs_nproc.soft},
+ {"rlimits/nproc.min", &slr->vs_nproc.min},
+
+ {"rlimits/rss.hard", &slr->vs_rss.hard},
+ {"rlimits/rss.soft", &slr->vs_rss.soft},
+ {"rlimits/rss.min", &slr->vs_rss.min},
+
+ {"rlimits/as.hard", &slr->vs_as.hard},
+ {"rlimits/as.soft", &slr->vs_as.soft},
+ {"rlimits/as.min", &slr->vs_as.min},
+
+ {"rlimits/openfd.hard", &slr->vs_openfd.hard},
+ {"rlimits/openfd.soft", &slr->vs_openfd.soft},
+ {"rlimits/openfd.min", &slr->vs_openfd.min},
+
+ {0,0}
+ };
+
+ sprintf(conf, "%s%s", VSERVERCONF, context);
+
+ slr->vs_rss.hard = VC_LIM_KEEP;
+ slr->vs_rss.soft = VC_LIM_KEEP;
+ slr->vs_rss.min = VC_LIM_KEEP;
+
+ slr->vs_as.hard = VC_LIM_KEEP;
+ slr->vs_as.soft = VC_LIM_KEEP;
+ slr->vs_as.min = VC_LIM_KEEP;
+
+ slr->vs_nproc.hard = VC_LIM_KEEP;
+ slr->vs_nproc.soft = VC_LIM_KEEP;
+ slr->vs_nproc.min = VC_LIM_KEEP;
+
+ slr->vs_openfd.hard = VC_LIM_KEEP;
+ slr->vs_openfd.soft = VC_LIM_KEEP;
+ slr->vs_openfd.min = VC_LIM_KEEP;
+
+ 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;
+ if (fgets(buf, sizeof(buf), fb) != NULL && isdigit(*buf))
+ *r->limit = atoi(buf);
+ fclose(fb);
+ }
+
+ fchdir(cwd);
+out_fd:
+ close(cwd);
+out:
+ free(conf);
+}
+
+int
+adjust_lim(const struct vc_rlimit *vcr, struct rlimit *lim)
+{
+ int adjusted = 0;
+ if (vcr->min != VC_LIM_KEEP) {
+ if (vcr->min > lim->rlim_cur) {
+ lim->rlim_cur = vcr->min;
+ adjusted = 1;