From taner@BOOM.extern.ucsd.edu Mon May 6 01:59:29 1996 Received: from BOOM.extern.ucsd.edu (taner@BOOM.extern.ucsd.edu [132.239.213.10]) by eterna.com.au (8.7.4/8.7.3) with ESMTP id BAA18946 for ; Mon, 6 May 1996 01:59:16 +1000 (EST) Received: from taner@localhost by BOOM.extern.ucsd.edu (8.7.3/BOOM-v1.5 PID 3214) id IAA03214; Sun, 5 May 1996 08:59:07 -0700 Message-Id: <199605051559.IAA03214@BOOM.extern.ucsd.edu> Date: Sun, 5 May 1996 08:59:07 -0700 From: taner@sdsc.edu Reply-To: taner@sdsc.edu To: ircii-bugs@eterna.com.au Cc: taner@sdsc.edu Subject: adds client-level load control (req. by several admins) X-Send-Pr-Version: 3.96 >Number: 95 >Category: change-request >Synopsis: adds client-level load control (req. by several admins) >Confidential: no >Severity: non-critical >Priority: medium >Responsible: mrg-pr (matthew green) >State: open >Class: change-request >Submitter-Id: net >Arrival-Date: Mon May 6 02:17:01 1996 >Last-Modified: >Originator: Taner Halicioglu >Organization: San Diego Supercomputer Center >Release: 2.8.15 >Environment: i486DX4/100, Linux 1.3.*, gcc2.7.2, libc 5.2.x System: Linux BOOM 1.3.94 #22 Tue Apr 23 12:19:20 PDT 1996 i486 Architecture: i486 >Description: This adds a call to /usr/bin/uptime (or wherever it lives) that gets called about once a minute. If the load average is greater than the specified maximum, the user is warned n number of times before being 'removed' from irc. This *may* break on systems with strange 'uptime' outputs - but can be easily changed. Works on Linux, SunOS, OSF/1 and IRIX (at least). >How-To-Repeat: >Fix: Patch is as follows (diff versus 2.8.15): [------------------------------------------------------------------------] diff -N -c -r ircii-2.8.15/ChangeLog.th ircii-2.8.15+th/ChangeLog.th *** ircii-2.8.15/ChangeLog.th Wed Dec 31 16:00:00 1969 --- ircii-2.8.15+th/ChangeLog.th Wed Mar 13 16:29:59 1996 *************** *** 0 **** --- 1,6 ---- + Taner's Changelog: + + * Added #define CHECK_LOAD... for all those sysadmins that want to be + able to disable the use of irc when your system is loaded. + You need to set: + UPTIME_PATH, MAX_LOAD, and MAX_WARN_LOAD in include/config.h diff -N -c -r ircii-2.8.15/include/config.h ircii-2.8.15+th/include/config.h *** ircii-2.8.15/include/config.h Wed Dec 13 15:53:13 1995 --- ircii-2.8.15+th/include/config.h Mon Apr 8 23:05:23 1996 *************** *** 86,91 **** --- 86,104 ---- #define PAUSE_AFTER_MOTD 1 /* + * Here we define whether or not we want to check system load levels, + * what the max acceptable level is, and how many warnings we will give + * before exiting. + */ + + #define CHECK_LOAD + #ifdef CHECK_LOAD + # define UPTIME_PATH "/usr/bin/uptime" + # define MAX_LOAD 5.00 + # define MAX_WARN_LOAD 3 + #endif /* CHECK_LOAD */ + + /* * Below are the IRCII variable defaults. For boolean variables, use 1 for * ON and 0 for OFF. You may set string variable to NULL if you wish them to * have no value. None of these are optional. You may *not* comment out or diff -N -c -r ircii-2.8.15/include/irc.h ircii-2.8.15+th/include/irc.h *** ircii-2.8.15/include/irc.h Wed Dec 6 06:49:16 1995 --- ircii-2.8.15+th/include/irc.h Tue Mar 12 17:46:48 1996 *************** *** 283,288 **** --- 283,296 ---- void parse_notice _((char *, char **)); void irc_quit _((unsigned char, char *)); + /* + * Load average stuff... -Taner + */ + #ifdef CHECK_LOAD + extern int load_warnings; + extern float load_AVG; + #endif /* CHECK_LOAD */ + typedef struct WhoisStuffStru { char *nick; diff -N -c -r ircii-2.8.15/source/irc.c ircii-2.8.15+th/source/irc.c *** ircii-2.8.15/source/irc.c Fri Mar 1 03:06:18 1996 --- ircii-2.8.15+th/source/irc.c Mon Apr 22 21:07:49 1996 *************** *** 81,86 **** --- 81,91 ---- waiting = 0, /* used by /WAIT command */ who_mask = 0; /* keeps track of which /who * switchs are set */ + #ifdef CHECK_LOAD + int load_warnings = 0; /* Number of warnings so far */ + float load_AVG = 0.0; /* Current load average */ + float update_load((int)); /* Get the current load avg */ + #endif /* CLIENT_LOAD */ char *zero = "0"; char *one = "1"; *************** *** 905,910 **** --- 910,920 ---- status_update(1); cursor_to_input(); } + #ifdef CHECK_LOAD + load_AVG = update_load(0); + /* We need to update the status bar */ + build_status((char *) 0); + #endif /* CHECK_LOAD */ if (primary_server != -1) do_notify(); } *************** *** 943,948 **** --- 953,961 ---- char *channel; start_time = time((time_t *)0); + #ifdef CHECK_LOAD + load_AVG = update_load(1); + #endif /* CHECK_LOAD */ #ifdef SOCKS SOCKSinit(argv[0]); #endif /* SOCKS */ *************** *** 1083,1085 **** --- 1096,1175 ---- irc_exit(); return; } + + #ifdef CHECK_LOAD + /* + * Check the current system load average. If it is above MAX_LOAD + * then warn the user, and increment the warning counter. + * If we exceed MAX_WARN_LOAD, then exit. + * Added by Taner Halicioglu (taner@SDSC.EDU) + */ + + float + update_load(int init_load) + { + FILE *fp; + char load[100]; + float load_1 = 0.0; + char l1[10], l5[10], l15[10]; + int done, fin, tmp; + + /* + * Since this (hopefully) will only err out once (the first time), + * we should use fprintf's to stderr since say(), etc won't work + * yet. Note, man page for popen() says it DOES NOT reliably set errno. + */ + if ((fp = popen(UPTIME_PATH,"r")) == NULL) { + fprintf(stderr,"HELP!! Please tell you admins that %s is not", + UPTIME_PATH) + fprintf(stderr,"the correct path to the 'uptime' executable!!"); + exit(-1); + } + done = 0; + while (!done) { + fin = fscanf(fp, "%s", load); + done = !strncmp(load, "averag", 6); + done = (done || (fin == EOF)); + } + fscanf(fp, "%s %s %s", l1, l5, l15); + if (tmp = (int)index(l1, ',')) l1[tmp - (int)l1] = 0; /* blow away the comma */ + pclose(fp); + load_1 = atof(l1); + if (load_1 >= MAX_LOAD) { + if (init_load) { + /* + * Internal IRC functions won't work here - nothing has been initialized + * so use normal fprintf() and exit(). -Taner + */ + fprintf(stderr,"Sorry, the system load is currently %.2f, which is greater\n", load_1); + fprintf(stderr,"than the allowed maximum of %.2f.\n", MAX_LOAD); + fprintf(stderr,"Please IRC later, or from another machine.\n"); + exit(-1); + } + if (++load_warnings > MAX_WARN_LOAD) { + say("\007\007Sorry, you have been warned %d times about the load", + MAX_WARN_LOAD); + say("average being too high to IRC. Terminating session."); + send_to_server("QUIT :System load average too high %.2f > %.2f", + load_1, MAX_LOAD); + irc_exit(); + } else { + say("\007%c* WARNING * WARNING * WARNING * WARNING * WARNING *%c", + REV_TOG, REV_TOG); + say("The system load average is currently %.2f.",load_1); + say("The maximum allowed level is %.2f.",MAX_LOAD); + say("This is warning number %d out of %d.", load_warnings, + MAX_WARN_LOAD); + if (load_warnings == MAX_WARN_LOAD) + say("%cThis is your last warning.%c", BOLD_TOG, BOLD_TOG); + } + } else if (load_warnings) { + say("%c* NOTICE * NOTICE * NOTICE * NOTICE * NOTICE * NOTICE *%c", + BOLD_TOG, BOLD_TOG); + say("The system load average has fallen back down to a level"); + say("where IRCing is allowed (%.2f).",load_1); + load_warnings = 0; + } + return load_1; + } + #endif /* CHECK_LOAD */ diff -N -c -r ircii-2.8.15/source/status.c ircii-2.8.15+th/source/status.c *** ircii-2.8.15/source/status.c Fri Jan 5 15:14:01 1996 --- ircii-2.8.15+th/source/status.c Tue Mar 12 18:41:20 1996 *************** *** 385,392 **** --- 385,409 ---- char *ptr, *malloc_ptr = (char *) 0; int *cp; + #ifdef CHECK_LOAD + char tmpstr[30]; + #endif /* CHECK_LOAD */ *buffer = (char) 0; + #ifdef CHECK_LOAD + *tmpstr = (char) 0; + /* + * Give them a visual reminder of the load on the status bar + * Put it only in the 'main' status bar. + */ + if (k == 0) { + sprintf(tmpstr,"Load: %.2f ", (float)load_AVG); + if (load_warnings) { + strcat(tmpstr, "*TOO HIGH* "); + } + } + strmcat(buffer, tmpstr, BIG_BUFFER_SIZE); + #endif /* CHECK_LOAD */ while (format) { if ((ptr = (char *) index(format, '%')) != NULL) [------------------------------------------------------------------------] >Audit-Trail: >Unformatted: