home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1989, University of Rochester
- * Department of Electrical Engineering
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * at the University of Rochester.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /* srvclnt.c version 1.1 3/7/89
- * for the 'lb' load balancer - by Deke Kassabian
- *
- * -Deke Kassabian, University of Rochester EE Department
- * ( deke@ee.rochester.edu ) (716) 275-3106
- */
-
- #include <sys/param.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <stdio.h>
- #include <string.h>
- #include "stats.h"
- #include "config.h"
-
- char *pname;
- short server = 0; /* indicates we aren't server */
- struct sockaddr_in sin; /* address of remote host */
-
- main(argc, argv, envp)
- int argc;
- char **argv;
- char **envp;
- {
- FILE *fd,*fopen();
-
- int start, /* where in the argv the command begins */
- ppgrp, /* parent process group */
- command, /* whether there is a command */
- verbose_mode, /* all possible output */
- quiet_mode; /* no output */
-
- char *path=RSH;
-
- char *dir;
- char *cmd_exec[MAXSHBUF], /* command to execute (local) */
- *rcmd_exec[MAXSHBUF], /* command to execute (remote) */
- dbuf[MAXSHBUF], /* working directory placeholder */
- host[MAXHOST], /* hostname placeholder */
- best_host[MAXHOST], /* hostname placeholder */
- fentry[MAXLINE]; /* file entry */
-
- float my_sfactor,
- best_sfactor,
- load,
- factor,limit; /* file variables */
-
- int socktype;
- register int s;
- char buf[10240];
- struct hostent *hp;
- struct servent *sp;
- char *servtype;
- struct hostent *gethostbyname();
- struct servent *getservbyname();
-
- pname = *argv; /* Name of this program */
-
- verbose_mode=0,quiet_mode=0; /* Default is neither */
- best_sfactor=MAXFLOAT; /* Practically infinity! */
- command=1; /* There is a command */
-
- /* Check arguments.
- *
- * if argc=1 then verbose=Y and command=NULL
- * if argc>=2 check for flags:
- * -v=verbose (full output), -q=quiet (don't output machine selection)
- * with no flags, only machine selection will be output
- * The above flags are mutually exclusive. v overrides q
- *
- * Additional arguments are taken to be a command. No sanity checking
- * will be done. When a machine is selected, the command will be run
- * on that machine
- *
- */
-
- if (argc == 1) {
- command=0; /* no command to execute */
- verbose_mode=1; /* verbose mode */
- }
- else {
- start=1;
- if(!strcmp(argv[1],"-q")){
- quiet_mode=1; /* quiet mode - no output */
- start=2;
- if(argc == 2) exit(0); /* No command, no output! */
- }
- if(!strcmp(argv[1],"-v")){
- verbose_mode=1; /* verbose mode */
- start=2;
- if(argc == 2) command=0; /* No command - verbose */
- }
- }
-
- if(command){
- for( ; start<argc; start++){
- strcat(cmd_exec," "); strcat(cmd_exec,argv[start]);
- }
- }
-
- /* Open the config file */
- if((fd=fopen(CONFIGFILE,"r"))==0){
- fprintf(stderr,"Error opening configuration file ");
- exit(1);
- }
-
- /* Set up to use TCP stream sockets. */
- servtype = "tcp";
- socktype = SOCK_STREAM;
-
- /* Look up the port the server lives on. */
- if ((sp = getservbyname(SERVNAME, servtype)) == NULL) {
- fprintf(stderr, "%s: %s/%s: service unknown.\n",
- pname, SERVNAME, servtype);
- exit(1);
- }
-
- /* Read the config file */
- strcpy(best_host,"localhost");
- while((fgets(fentry,MAXLINE,fd))!=NULL){
- sscanf(fentry,"%s %f %f",host,&factor,&limit);
- if(fentry[0]=='#') continue; /*ignore comments*/
-
- if(verbose_mode)
- printf("\nHOST=%s\tFACTOR=%.2f\tLIMIT=%.2f\n",host,factor,limit);
-
-
- /* Look up the host's address. */
- if ((hp = gethostbyname(host)) == NULL) {
- fprintf(stderr, "%s: %s: host unknown.\n", pname, host);
- exit(1);
- }
-
- /* Get a socket. */
- if ((s = socket(AF_INET, socktype, 0)) < 0) {
- error("socket");
- exit(1);
- }
-
- /* Build the server's address. */
- sin.sin_port = sp->s_port;
- sin.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, &sin.sin_addr, sizeof(sin.sin_addr));
-
- /* connect to the remote host. */
- if (connect(s, &sin, sizeof(struct sockaddr_in)) < 0) {
- /* if not quiet mode, print connect error */
- error("connect");
- /* can't reach this host, try the next */
- continue;
- }
-
- /* make the request and grab the result */
- st_send(s,"loadav");
- st_recv(s,buf,sizeof(buf),"response");
- sscanf(buf,"%f",&load);
-
- if( load > limit){
- if(verbose_mode)
- printf("Host %s is over defined limit\n",host);
- continue;
- }
-
- my_sfactor=100*( load / factor );
- if(verbose_mode){
- printf("Load avg=%.3f ",load);
- printf("Selection factor=%.2f\n",my_sfactor);
- }
-
- if(best_sfactor>my_sfactor){
- best_sfactor=my_sfactor;
- strcpy(best_host,host);
- }
-
- } /*endwhile */
-
- if(verbose_mode)
- printf("Selected host: <%s> factor=<%.3f>\n",best_host,best_sfactor);
-
- if(command){
- sprintf(rcmd_exec,"(cd %s;%s)",getwd(dbuf),cmd_exec);
- if(!quiet_mode){ /* print if not quiet_mode */
- printf("\nrsh %s %s &\n",best_host,rcmd_exec);
- }
- ppgrp = getpgrp(getppid());
- if (fork())
- exit(0);
- if(setpgrp(getpid(), ppgrp))
- perror("stepgrp");
- execle(path,path,best_host,rcmd_exec,(char *)0,envp); exit(0);
- perror("");
- }
- exit(0);
- }
-
- error(s)
- {
- fprintf(stderr, "%s: ", pname); perror(s);
- }
-