home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / condor40.zip / CONDOR / src / condor_collect / event.c < prev    next >
C/C++ Source or Header  |  1989-09-05  |  8KB  |  319 lines

  1. /* 
  2. ** Copyright 1986, 1987, 1988, 1989 University of Wisconsin
  3. ** 
  4. ** Permission to use, copy, modify, and distribute this software and its
  5. ** documentation for any purpose and without fee is hereby granted,
  6. ** provided that the above copyright notice appear in all copies and that
  7. ** both that copyright notice and this permission notice appear in
  8. ** supporting documentation, and that the name of the University of
  9. ** Wisconsin not be used in advertising or publicity pertaining to
  10. ** distribution of the software without specific, written prior
  11. ** permission.  The University of Wisconsin makes no representations about
  12. ** the suitability of this software for any purpose.  It is provided "as
  13. ** is" without express or implied warranty.
  14. ** 
  15. ** THE UNIVERSITY OF WISCONSIN DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. ** THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. ** FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF WISCONSIN  BE LIABLE FOR
  18. ** ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. ** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ** ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  21. ** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22. ** 
  23. ** Authors:  Allan Bricker and Michael J. Litzkow,
  24. **              University of Wisconsin, Computer Sciences Dept.
  25. ** 
  26. */ 
  27.  
  28.  
  29. #include <stdio.h>
  30. #include <signal.h>
  31. #include <netdb.h>
  32. #include <pwd.h>
  33. #include <errno.h>
  34. #include <sys/types.h>
  35. #include <sys/time.h>
  36. #include <sys/param.h>
  37. #include <sys/socket.h>
  38. #include <sys/ioctl.h>
  39. #include <netinet/in.h>
  40. #include <rpc/types.h>
  41. #include <rpc/xdr.h>
  42. #include "condor_types.h"
  43. #include "sched.h"
  44. #include "debug.h"
  45. #include "trace.h"
  46. #include "except.h"
  47. #include "expr.h"
  48. #include "manager.h"
  49. #include "clib.h"
  50.  
  51. #ifndef LINT
  52. static char *_FileName_ = __FILE__;        /* Used by EXCEPT (see except.h)     */
  53. #endif LINT
  54.  
  55. CONTEXT        *create_context();
  56. EXPR        *build_expr();
  57. char        *calloc(), *strdup();
  58. MACH_REC    *find_mach_rec(), *create_mach_rec();
  59. bool_t         xdr_int();
  60.  
  61.  
  62. MACH_REC    *MachineList;
  63.  
  64. STATUS_LINE    *StatusLines[1024];
  65. int            N_StatusLines;
  66. int            MachineUpdateInterval;
  67.  
  68. negotiator_info( xdrs )
  69. XDR        *xdrs;
  70. {
  71.     PRIO_REC    record, *rec = &record;
  72.  
  73.     for(;; ) {
  74.         bzero( (char *)rec, sizeof(PRIO_REC) );
  75.         if( !xdr_prio_rec(xdrs,rec) ) {
  76.             dprintf( D_ALWAYS, "Can't read prio_rec from negotiator\n" );
  77.             return;
  78.         }
  79.         if( rec->name == NULL ) {
  80.             return;
  81.         }
  82.         if(  rec->name[0] == '\0' ) {
  83.             free( rec->name );
  84.             return;
  85.         }
  86.         update_prio( rec );
  87.         free( rec->name );
  88.     }
  89. }
  90.  
  91. update_prio( rec )
  92. PRIO_REC    *rec;
  93. {
  94.     int    i;
  95.  
  96.     for( i=0; i<N_StatusLines; i++ ) {
  97.         if( strcmp(StatusLines[i]->name,rec->name) == MATCH ) {
  98.             StatusLines[i]->prio = rec->prio;
  99.             return;
  100.         }
  101.     }
  102.     dprintf( D_ALWAYS, "Can't find status line for \"%s\"\n", rec->name );
  103. }
  104.  
  105. STATUS_LINE    Endmarker;
  106. give_status_lines( xdrs )
  107. XDR    *xdrs;
  108. {
  109.     int        i;
  110.  
  111.     if( !xdrrec_skiprecord(xdrs) ) {
  112.         dprintf( D_ALWAYS, "Can't send mach_rec to client\n" );
  113.         return;
  114.     }
  115.  
  116.     xdrs->x_op = XDR_ENCODE;
  117.  
  118.     for( i=0; i<N_StatusLines; i++ ) {
  119.         if( !xdr_status_line(xdrs,StatusLines[i]) ) {
  120.             dprintf( D_ALWAYS, "Can't send StatusLine to client\n" );
  121.             return;
  122.         }
  123.     }
  124.     if( !xdr_status_line(xdrs,&Endmarker) ) {
  125.         dprintf( D_ALWAYS, "Can't send Endmarker to client\n" );
  126.         return;
  127.     }
  128.  
  129.     (void)xdrrec_endofrecord( xdrs, TRUE );
  130. }
  131.  
  132. machine_info( xdrs, from, kind )
  133. XDR        *xdrs;
  134. struct sockaddr_in    *from;
  135. int        kind;
  136. {
  137.     MACH_REC    *rec;
  138.  
  139.     if( (rec = find_mach_rec(from)) == NULL ) {
  140.         rec = create_mach_rec( from );
  141.         insque( (struct qelem *)rec, (struct qelem *)MachineList );
  142.         dprintf( D_ALWAYS, "Creating new record for \"%s\"\n", rec->name );
  143.     } else {
  144.         /*
  145.         */
  146.         if( kind == STARTD_INFO ) {
  147.             dprintf( D_ALWAYS, "STARTD update for \"%s\"\n", rec->name );
  148.         } else {
  149.             dprintf( D_ALWAYS, "SCHEDD update for \"%s\"\n", rec->name );
  150.         }
  151.     }
  152.  
  153.     if( rec->machine_context == NULL ) {
  154.         rec->machine_context = create_context();
  155.     }
  156.     if( !xdr_context(xdrs,rec->machine_context) ) {
  157.         dprintf( D_ALWAYS, "Can't read mahcine context from client\n" );
  158.         free_context( rec->machine_context );
  159.         rec->machine_context = NULL;
  160.         return;
  161.     }
  162.     rec->time_stamp = time( (time_t *)0 );
  163.  
  164.     if( kind == STARTD_INFO ) {
  165.         rec->busy = FALSE;
  166.     }
  167.  
  168.     update_status_line( rec );
  169.  
  170. }
  171.  
  172. update_status_line( rec )
  173. MACH_REC    *rec;
  174. {
  175.     int            idle;
  176.     STATUS_LINE    *line = rec->line;
  177.  
  178.     if( line->name == NULL ) {
  179.         line->name = strdup( rec->name );
  180.     }
  181.     (void) evaluate_int( "Running", &line->run, rec->machine_context,
  182.                                                             (CONTEXT *)0 );
  183.     (void) evaluate_int( "Idle", &idle, rec->machine_context, (CONTEXT *)0 );
  184.     line->tot = line->run + idle;
  185.     free( line->state );
  186.     (void) evaluate_string( "State", &line->state, rec->machine_context,
  187.                                                                 (CONTEXT *)0 );
  188.     (void) evaluate_float( "LoadAvg", &line->load_avg, rec->machine_context,
  189.                                                                 (CONTEXT *)0 );
  190.     (void) evaluate_int( "KeyboardIdle", &line->kbd_idle, rec->machine_context,
  191.                                                                 (CONTEXT *)0);
  192.     if( line->arch == NULL ) {
  193.         (void) evaluate_string( "Arch", &line->arch, rec->machine_context,
  194.                                                                 (CONTEXT *)0 );
  195.     }
  196.     if( line->op_sys == NULL ) {
  197.         (void) evaluate_string( "OpSys", &line->op_sys, rec->machine_context,
  198.                                                                 (CONTEXT *)0 );
  199.     }
  200. }
  201.  
  202. MACH_REC    *
  203. find_mach_rec( from )
  204. struct sockaddr_in    *from;
  205. {
  206.     MACH_REC    *ptr;
  207.  
  208.     for( ptr = MachineList->next; ptr->name; ptr = ptr->next ) {
  209.         if( ptr->net_addr.s_addr == from->sin_addr.s_addr ) {
  210.             return ptr;
  211.         }
  212.     }
  213.     return NULL;
  214. }
  215.  
  216. STATUS_LINE    *
  217. create_status_line()
  218. {
  219.     STATUS_LINE    *line;
  220.  
  221.     line = (STATUS_LINE *)calloc( 1, sizeof(STATUS_LINE) );
  222.     StatusLines[ N_StatusLines++ ] = line;
  223.     return line;
  224. }
  225.  
  226. MACH_REC    *
  227. create_mach_rec( from )
  228. struct sockaddr_in    *from;
  229. {
  230.     MACH_REC    *answer;
  231.     ELEM        tmp;
  232.     struct hostent    *hp, *gethostbyaddr();
  233.  
  234.     answer = (MACH_REC *)calloc( 1, sizeof(MACH_REC) );
  235.  
  236.     answer->next = answer;
  237.     answer->prev = answer;
  238.     answer->machine_context = create_context();
  239.     if( !from ) {
  240.         /*
  241.         dprintf( D_ALWAYS, "Created NULL machine record\n" );
  242.         */
  243.         return answer;
  244.     }
  245.  
  246.     answer->net_addr = from->sin_addr;
  247.     answer->net_addr_type = from->sin_family;
  248.     answer->time_stamp = time( (time_t *)0 );
  249.  
  250.     if( (hp=gethostbyaddr((char *)&from->sin_addr,sizeof(struct in_addr),
  251.                                                 from->sin_family)) == NULL ) {
  252.         dprintf( D_ALWAYS, "Can't find host name for \"%s\"\n",
  253.                                             inet_ntoa(from->sin_addr) );
  254.  
  255.  
  256.  
  257.         free_mach_rec( answer );
  258.         return NULL;
  259.     }
  260.     answer->name = strdup( hp->h_name );
  261.  
  262.     tmp.type = INT;
  263.     tmp.i_val = 0;
  264.     store_stmt( build_expr("Users",&tmp), answer->machine_context );
  265.     store_stmt( build_expr("Running",&tmp), answer->machine_context );
  266.     store_stmt( build_expr("Idle",&tmp), answer->machine_context );
  267.     store_stmt( build_expr("Prio",&tmp), answer->machine_context );
  268.  
  269.     answer->line = create_status_line();
  270.     return answer;
  271. }
  272.  
  273. free_mach_rec( rec )
  274. MACH_REC    *rec;
  275. {
  276.     if( rec->name ) {
  277.         free( rec->name );
  278.     }
  279.  
  280.     if( rec->machine_context ) {
  281.         free_context( rec->machine_context );
  282.     }
  283.     free( (char *)rec );
  284. }
  285.  
  286. give_status( xdrs )
  287. XDR        *xdrs;
  288. {
  289.     MACH_REC    *ptr;
  290.  
  291.  
  292.     if( !xdrrec_skiprecord(xdrs) ) {
  293.         dprintf( D_ALWAYS, "Can't send mach_rec to client\n" );
  294.         return;
  295.     }
  296.  
  297.     xdrs->x_op = XDR_ENCODE;
  298.     for( ptr=MachineList->next; ptr->name; ptr = ptr->next ) {
  299.         if( (int)time( (time_t *)0 ) - ptr->time_stamp >
  300.                                                 MachineUpdateInterval ) {
  301.                 /* Doesn't belong here, but it's the only place we
  302.                    traverse the entire machine list. */
  303.             free( ptr->line->state );
  304.             ptr->line->state = strdup( "(DOWN)" );
  305.         }
  306.  
  307.         if( !xdr_mach_rec(xdrs,ptr) ) {
  308.             dprintf( D_ALWAYS, "Can't send mach_rec to client\n" );
  309.             return;
  310.         }
  311.     }
  312.     if( !xdr_mach_rec(xdrs,ptr) ) {
  313.         dprintf( D_ALWAYS, "Can't send mach_rec to client\n" );
  314.         return;
  315.     }
  316.  
  317.     xdrrec_endofrecord( xdrs, TRUE );
  318. }
  319.