X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fvsched.c;h=40fe83d2a4e6d74c52b687ff3d8ac05b997d0be8;hb=fc28db1eb4146796ec27c2fb15780d6303120261;hp=6f93a610ab723fab18567d7272d39b7bcdb86d58;hpb=8cf13bb177d92c93eb73dc8939777150536c2d00;p=util-vserver.git diff --git a/src/vsched.c b/src/vsched.c index 6f93a61..40fe83d 100644 --- a/src/vsched.c +++ b/src/vsched.c @@ -1,6 +1,7 @@ -// $Id: vsched.c,v 1.6 2004/12/21 07:19:20 ensc Exp $ --*- c -*-- +// $Id: vsched.c 2408 2006-11-27 14:06:57Z dhozac $ --*- c -*-- // Copyright (C) 2004 Enrico Scholz +// Copyright (C) 2006 Daniel Hokka Zakrisson // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -27,10 +28,17 @@ #include #include #include +#include +#include +#include +#include #define ENSC_WRAPPERS_PREFIX "vsched: " #define ENSC_WRAPPERS_VSERVER 1 #define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_FCNTL 1 +#define ENSC_WRAPPERS_DIRENT 1 +#define ENSC_WRAPPERS_STAT 1 #include #define CMD_HELP 0x1000 @@ -43,6 +51,14 @@ #define CMD_TOK_MAX 0x4005 #define CMD_CPU_MASK 0x4006 #define CMD_PRIO_BIAS 0x4007 +#define CMD_FRATE2 0x4008 +#define CMD_INTERVAL2 0x4009 +#define CMD_CPUID 0x400a +#define CMD_BUCKETID 0x400b +#define CMD_FORCE 0x400c +#define CMD_IDLE_TIME 0x400d +#define CMD_DIR 0x400e +#define CMD_MISSING 0x400f int wrapper_exit_code = 255; @@ -64,9 +80,39 @@ CMDLINE_OPTIONS[] = { { "priority_bias", required_argument, 0, CMD_PRIO_BIAS }, { "priority-bias", required_argument, 0, CMD_PRIO_BIAS }, { "cpu_mask", required_argument, 0, CMD_CPU_MASK }, + { "fill-rate2", required_argument, 0, CMD_FRATE2 }, + { "interval2", required_argument, 0, CMD_INTERVAL2 }, + { "cpu-id", required_argument, 0, CMD_CPUID }, + { "bucket-id", required_argument, 0, CMD_BUCKETID }, + { "force", no_argument, 0, CMD_FORCE }, + { "idle-time", no_argument, 0, CMD_IDLE_TIME }, + { "dir", required_argument, 0, CMD_DIR }, + { "missingok", no_argument, 0, CMD_MISSING }, {0,0,0,0} }; +struct sched_opt { + const char * const name; + uint_least32_t mask; + size_t offset; +}; +#define FOPT(NAME,MASK,FIELD) { #NAME, MASK, offsetof(struct vc_set_sched, FIELD) } +static struct sched_opt FILE_OPTIONS[] = { + FOPT(fill-rate, VC_VXSM_FILL_RATE, fill_rate), + FOPT(interval, VC_VXSM_INTERVAL, interval), + FOPT(tokens, VC_VXSM_TOKENS, tokens), + FOPT(tokens-min, VC_VXSM_TOKENS_MIN, tokens_min), + FOPT(tokens-max, VC_VXSM_TOKENS_MAX, tokens_max), + FOPT(prio-bias, VC_VXSM_PRIO_BIAS, priority_bias), + FOPT(priority-bias, VC_VXSM_PRIO_BIAS, priority_bias), + FOPT(fill-rate2, VC_VXSM_FILL_RATE2|VC_VXSM_IDLE_TIME, fill_rate2), + FOPT(interval2, VC_VXSM_INTERVAL2|VC_VXSM_IDLE_TIME, interval2), + FOPT(cpu-id, VC_VXSM_CPU_ID, cpu_id), + FOPT(bucket-id, VC_VXSM_BUCKET_ID, bucket_id), + FOPT(idle-time, VC_VXSM_IDLE_TIME, set_mask), + {0,0,0} +}; + static void showHelp(int fd, char const *cmd, int res) { @@ -75,9 +121,25 @@ showHelp(int fd, char const *cmd, int res) WRITE_MSG(fd, "Usage:\n "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " [--xid ] [--fill-rate ] [--interval ] [--tokens ] [--tokens-min ] [--tokens-max ] [--prio-bias ] [--] [ *]\n" + " [--xid ] * [--dir ] [--] [ *]\n" "\n" - "Please report bugs to " PACKAGE_BUGREPORT "\n"); + "Options:\n" + " --fill-rate \n" + " --interval \n" + " --tokens \n" + " --tokens-min \n" + " --tokens-max \n" + " --prio-bias \n" + " --fill-rate2 \n" + " --interval2 \n" + " --cpu-id \n" + " --bucket-id \n" + " --idle-time ... set the idle time flag; this is required for\n" + " all updates to the scheduler to keep it enabled\n" + " --force ... force update of all per-CPU schedulers now\n" + " --dir ... read settings from \n" + " --missingok ... do not fail when does not exist\n" + "\nPlease report bugs to " PACKAGE_BUGREPORT "\n"); exit(res); } @@ -89,20 +151,115 @@ showVersion() "vsched " VERSION " -- modifies scheduling parameters\n" "This program is part of " PACKAGE_STRING "\n\n" "Copyright (C) 2003,2004 Enrico Scholz\n" + "Copyright (C) 2006 Daniel Hokka Zakrisson\n" VERSION_COPYRIGHT_DISCLAIMER); exit(0); } +static void do_dir_entry(struct vc_set_sched *sched, const char *name) +{ + int fd; + char buf[128]; + signed long val; + struct sched_opt *opt; + ssize_t len; + char *newline; + + for (opt = FILE_OPTIONS; opt->name != 0; opt++) { + if (strcmp(name, opt->name) == 0) + break; + } + if (opt->name == 0) + return; + + fd = Eopen(name, O_RDONLY, 0); + len = Eread(fd, buf, sizeof(buf)-1); + Eclose(fd); + buf[len] = '\0'; + if ((newline=strchr(buf, '\n')) != NULL) + *newline = '\0'; + + if (!isNumber(buf, &val, true)) { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX); + WRITE_STR(2, name); + WRITE_MSG(2, ": is not a number\n"); + exit(1); + } + + if (opt->offset != offsetof(struct vc_set_sched, set_mask)) + *(int_least32_t *)(((char *)sched)+opt->offset) = (int_least32_t) val; + + sched->set_mask |= opt->mask; +} + +static void do_dir(xid_t xid, struct vc_set_sched *sched, const char *dir, int missing_ok, int per_cpu) +{ + DIR *dp; + struct dirent *de; + int cur_fd = Eopen(".", O_RDONLY, 0); + struct stat st; + + if (chdir(dir)!=-1) { + dp = Eopendir("."); + while ((de = Ereaddir(dp)) != NULL) { + if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) + continue; + Estat(de->d_name, &st); + if (S_ISDIR(st.st_mode)) + continue; + do_dir_entry(sched, de->d_name); + } + + /* set the values now */ + if (vc_set_sched(xid, sched) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_set_sched()"); + exit(1); + } + + if (!per_cpu) { + struct vc_set_sched per_cpu_sched; + + rewinddir(dp); + while ((de = Ereaddir(dp)) != NULL) { + if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) + continue; + Estat(de->d_name, &st); + if (S_ISDIR(st.st_mode)) { + per_cpu_sched.set_mask = sched->set_mask & (VC_VXSM_IDLE_TIME|VC_VXSM_FORCE); + do_dir(xid, &per_cpu_sched, de->d_name, 0, 1); + } + } + } + + Eclosedir(dp); + } + else if (!missing_ok) { + perror(ENSC_WRAPPERS_PREFIX "chdir()"); + exit(wrapper_exit_code); + } + + Efchdir(cur_fd); +} + #define SETVAL(ATTR,MASK) \ - sched.ATTR = atoi(optarg); \ - sched.set_mask |= MASK; + if (!isNumber(optarg, &tmp, false)) { \ + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "non-numeric value specified for '--" #ATTR "'\n"); \ + exit(wrapper_exit_code); \ + } \ + else { \ + sched.ATTR = tmp; \ + sched.set_mask |= MASK; \ + } int main(int argc, char *argv[]) { xid_t xid = VC_NOCTX; + signed long tmp; struct vc_set_sched sched = { .set_mask = 0 }; + const char *dir = NULL; + int missing_ok = 0; while (1) { int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0); @@ -121,10 +278,18 @@ int main(int argc, char *argv[]) case CMD_CPU_MASK : WRITE_MSG(2, "vsched: WARNING: the '--cpu_mask' parameter is deprecated and will not have any effect\n"); break; + case CMD_FRATE2 : SETVAL(fill_rate2, VC_VXSM_FILL_RATE2); break; + case CMD_INTERVAL2: SETVAL(interval2, VC_VXSM_INTERVAL2); break; + case CMD_CPUID : SETVAL(cpu_id, VC_VXSM_CPU_ID); break; + case CMD_BUCKETID : SETVAL(bucket_id, VC_VXSM_BUCKET_ID); break; + case CMD_DIR : dir = optarg; break; + case CMD_MISSING : missing_ok = 1; break; + case CMD_FORCE : sched.set_mask |= VC_VXSM_FORCE; break; + case CMD_IDLE_TIME: sched.set_mask |= VC_VXSM_IDLE_TIME; break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); - WRITE_MSG(2, " --help\" for more information.\n"); + WRITE_MSG(2, " --help' for more information.\n"); return EXIT_FAILURE; break; } @@ -135,7 +300,7 @@ int main(int argc, char *argv[]) exit(wrapper_exit_code); } - if (sched.set_mask==0 && optind==argc) { + if (sched.set_mask==0 && dir==NULL && optind==argc) { WRITE_MSG(2, "Neither an option nor a program was specified; try '--help' for more information\n"); exit(wrapper_exit_code); } @@ -143,9 +308,14 @@ int main(int argc, char *argv[]) if (xid==VC_NOCTX) xid = Evc_get_task_xid(0); - if (sched.set_mask!=0 && vc_set_sched(xid, &sched)==-1) { - perror("vc_set_sched()"); - exit(255); + if (dir) { + do_dir(xid, &sched, dir, missing_ok, 0); + } + else { + if (sched.set_mask!=0 && vc_set_sched(xid, &sched)==-1) { + perror("vc_set_sched()"); + exit(255); + } } if (optind