/* Author(s): Ariel Rosenblatt, Amnon Shiloh for Mosix */ /* Code derived from previous work by Amnon Shiloh and Oren Laadan. */ /* Adapted to OpenMosix from Mosix and bugfixing by David Santo Orcero */ /* irbis@orcero.org http://www.orcero.org/irbis */ /* Mosix is (c) of prof. Amnon Barak http://www.mosix.org */ /* Original code is (c) of prof. Amnon Barak http://www.mosix.org */ /* OpenMosix is (c) of Moshe Bar http://www.openmosix.com */ /* Each respective trademark is of its own owner */ /* All rights reserved. */ /* This software is distributed under GPL 2 */ /* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTY IS ASSUMED. */ /* NO LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING */ /* FROM THE USE OF THIS SOFTWARE WILL BE ACCEPTED. IT CAN BURN */ /* YOUR HARD DISK, ERASE ALL YOUR DATA AND BROKE DOWN YOUR */ /* MICROWAVE OVEN. YOU ARE ADVISED. */ /* THIS SOFTWARE IS PROVIDED IN ITS "AS IS" CONDITION, WITH NO WARRANTY */ /* WHATSOEVER. NO LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING*/ /* FROM THE USE OF THIS SOFTWARE WILL BE ACCEPTED. */ #include "mos.h" int64_t msxctl(msx_cmd_t cmd, int arg, void *resp, int len) { struct mosixnet config[MAX_MOSNET_ENTS]; struct decay_params *dec; struct process_info *pinfo; int val; int64_t ofast, oslow, ointerval; switch(cmd) { case D_STAY: return(msx_replace("/proc/hpc/admin/stay", 1)); case D_NOSTAY: return(msx_replace("/proc/hpc/admin/stay", 0)); case D_LSTAY: return(msx_replace("/proc/hpc/admin/lstay", 1)); case D_NOLSTAY: return(msx_replace("/proc/hpc/admin/lstay", 0)); case D_BLOCK: return(msx_replace("/proc/hpc/admin/block", 1)); case D_NOBLOCK: return(msx_replace("/proc/hpc/admin/block", 0)); case D_EXPEL: return(msx_write("/proc/hpc/admin/expel", 1)); case D_BRING: return(msx_write("/proc/hpc/admin/bring", 1)); case D_QUIET: return(msx_replace("/proc/hpc/admin/quiet", 1)); case D_NOQUIET: return(msx_replace("/proc/hpc/admin/quiet", 0)); case D_MFS: return(msx_replace("/proc/hpc/admin/nomfs", 0)); case D_NOMFS: return(msx_replace("/proc/hpc/admin/nomfs", 1)); case D_GETSSPEED: return(msx_read("/proc/hpc/admin/sspeed")); case D_SETSSPEED: return(msx_write("/proc/hpc/admin/sspeed", arg)); case D_GETSPEED: return(msx_readnode(arg, "speed")); case D_SETSPEED: return(msx_write("/proc/hpc/admin/speed", arg)); case D_GETLOAD: return(msx_readnode(arg, "load")); case D_GETMEM: if((*((int64_t *)resp) = msx_readnode(arg, "tmem")) == -1) return(-1); return(msx_readnode(arg, "mem")); case D_GETRMEM: if((*((int64_t *)resp) = msx_readnode(arg, "tmem")) == -1) return(-1); return(msx_readnode(arg, "rmem")); case D_GETSTAT: return(msx_readnode(arg, "status")); case D_GETUTIL: return(msx_readnode(arg, "util")); case D_GETPE: return(msx_read("/proc/hpc/admin/mospe")); case D_GETCPUS: return(msx_readnode(arg, "cpus")); case D_GETLOADLOCAL: return(msx_readnode(arg, "loadlocal")); case D_GETLOADREMOTE: return (msx_readnode(arg, "loadremote")); case D_GETCPULOCAL: return (msx_readnode(arg, "cpulocal")); case D_GETCPUREMOTE: return (msx_readnode(arg,"cpuremote")); case D_SETLOADLIMIT: return (msx_write("/proc/hpc/admin/loadlimit", arg)); case D_SETLLIMITMODE: return (msx_write("/proc/hpc/admin/llimitmode", arg)); case D_SETCPULIMIT: return (msx_write("/proc/hpc/admin/cpulimit", arg)); case D_SETCPULIMITMODE: return (msx_write("/proc/hpc/admin/cpulimitmode", arg)); case D_GETLOADLIMIT: return (msx_readnode(arg, "loadlimit")); case D_GETLLIMITMODE: return (msx_readnode(arg, "llimitmode")); case D_GETCPULIMIT: return (msx_readnode(arg, "cpulimit")); case D_GETCPULIMITMODE: return (msx_readnode(arg, "cpulimitmode")); case D_MOSIX_TO_IP: { int i; int total; total = msx_readdata("/proc/hpc/admin/config", config, MAX_MOSNET_ENTS, sizeof(struct mosixnet)); if(total <= 0) return(-1); for(i = 0 ; i < total && (arg < config[i].base || arg > config[i].base + config[i].cnt - 1) ; i++) ; if (i < total) { struct in_addr in = (*((struct sockaddr_in *) &(config[i].saddr))).sin_addr; in.s_addr = ntohl(in.s_addr); in.s_addr += arg - config[i].base; in.s_addr = htonl(in.s_addr); strcpy(resp, inet_ntoa(in)); } else { errno = ENOENT; return -1; } return 0; } case D_IP_TO_MOSIX: if (arg == 0) return(msx_read("/proc/hpc/admin/mospe")); { struct in_addr in; int total; int i; total = msx_readdata("/proc/hpc/admin/config", config, MAX_MOSNET_ENTS, sizeof(struct mosixnet)); if(total <= 0) return(-1); for(i = 0 ; i < total ; i++) if(config[i].cnt) { in = (*((struct sockaddr_in *) &(config[i].saddr))).sin_addr; in.s_addr = ntohl(in.s_addr); if((unsigned)arg >= in.s_addr && (unsigned)arg < in.s_addr + config[i].cnt) return(config[i].base + ((unsigned)arg - in.s_addr)); } errno = ENOENT; return -1; } case D_GETNTUNE: return(msx_count_ints("/proc/hpc/admin/overheads")); case D_GETTUNE: return(msx_fill_ints("/proc/hpc/admin/overheads", (int *)resp, len)); case D_SETDECAY: errno = EINVAL; dec = (struct decay_params*)arg; if(dec->interval < 1 || dec->interval > 65535 || dec->fast < 0 || dec->slow < dec->fast || dec->slow > DECAY_QUOTIENT) return(-1); if(!msx_readval("/proc/hpc/admin/slowdecay", &oslow) || !msx_readval("/proc/hpc/admin/fastdecay", &ofast) || !msx_readval("/proc/hpc/admin/decayinterval", &ointerval)) return(-1); if(!msx_write("/proc/hpc/admin/decayinterval", dec->interval)) return(-1); if(dec->slow < ofast) { if(!msx_write("/proc/hpc/admin/fastdecay", dec->fast)) { restinterval: val = errno; msx_write("/proc/hpc/admin/decayinterval", dec->interval); errno = val; return(-1); } if(!msx_write("/proc/hpc/admin/slowdecay", dec->slow)) { val = errno; msx_write("/proc/hpc/admin/fastdecay", ofast); errno = val; goto restinterval; return(-1); } } else { if(!msx_write("/proc/hpc/admin/slowdecay", dec->slow)) goto restinterval; if(!msx_write("/proc/hpc/admin/fastdecay", dec->fast)) { val = errno; msx_write("/proc/hpc/admin/slowdecay", oslow); errno = val; goto restinterval; } } return 0; case D_GETDECAY: dec = (struct decay_params*)resp; if ((dec->interval = msx_read("/proc/hpc/admin/decayinterval")) == -1 || (dec->slow = msx_read("/proc/hpc/admin/slowdecay")) == -1 || (dec->fast = msx_read("/proc/hpc/admin/fastdecay")) == -1) return -1; return 0; case D_SETWHERETO: pinfo = (struct process_info*)arg; return(msx_writeproc(pinfo->pid, "goto", pinfo->where)); default: return(-1); } } int msx_lock(void) { return(msx_write("/proc/self/lock", 1)); } int msx_unlock(void) { return(msx_write("/proc/self/lock", 0)); } int msx_get_own(int *decay, int *time) { return(msx_readval2("/proc/hpc/decay/own", decay, time)); } int msx_get_decayinterval(void) { return(msx_read("/proc/hpc/admin/decayinterval")); } int msx_get_fast(void) { return(msx_read("/proc/hpc/decay/fast")); } int msx_get_slow(void) { return(msx_read("/proc/hpc/decay/slow")); } int msx_get_cpujob(void) { return(msx_read("/proc/hpc/decay/cpujob")); } int msx_get_iojob(void) { return(msx_read("/proc/hpc/decay/iojob")); } int msx_get_slowdecay(void) { return(msx_read("/proc/hpc/admin/slowdecay")); } int msx_get_fastdecay(void) { return(msx_read("/proc/hpc/admin/fastdecay")); } int msx_migrate(int where) { return(msx_write("/proc/self/migrate", where)); } int msx_where_is(pid_t pid) { return(msx_readproc(pid, "where")); } int msx_is_lock(pid_t pid) { return(msx_readproc(pid, "lock")); } int msx_send(pid_t pid, int node) { return(msx_writeproc(pid, "goto", node)); } int msx_get_nmigs(pid_t pid) { return(msx_readproc(pid, "nmigs")); } int msx_where_am_i(void) { return(msx_read("/proc/self/where")); } int msx_self_is_lock(void) { return(msx_read("/proc/self/lock")); } int msx_self_get_nmigs(void) { return(msx_read("/proc/self/nmigs")); } int msx_send_back_home(pid_t pid) { return(msx_writeproc(pid, "goto", D_GOBACKHOME)); } int msx_go_back_home() { return(msx_write("/proc/self/migrate", D_GOBACKHOME)); }