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_tools / status.c < prev    next >
C/C++ Source or Header  |  1989-09-02  |  9KB  |  506 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 <rpc/types.h>
  31. #include <rpc/xdr.h>
  32. #include <netinet/in.h>
  33. #include <netdb.h>
  34. #include <ctype.h>
  35. #include "debug.h"
  36. #include "except.h"
  37. #include "trace.h"
  38. #include "expr.h"
  39. #include "sched.h"
  40. #include "manager.h"
  41. #include "clib.h"
  42.  
  43. static char *_FileName_ = __FILE__;        /* Used by EXCEPT (see except.h)     */
  44.  
  45. char    *param(), *strdup();
  46. XDR        *xdr_Init();
  47. CONTEXT    *create_context();
  48.  
  49. extern int    Terse;
  50. extern int    Silent;
  51.  
  52. char    *CollectorHost;
  53. char    *MyName;
  54. int        Verbose;
  55. int        SortByPrio;
  56. int        RollCall;
  57. char    *RosterFile;
  58.  
  59. STATUS_LINE        *StatusLines[1024];
  60. int                N_StatusLines;
  61.  
  62. typedef struct {
  63.     char    *name;
  64.     char    *comment;
  65.     int        present;
  66. } ROSTER;
  67.  
  68. ROSTER    Roster[1024];
  69. int        RosterLen = 0;
  70. int        Absent;
  71.  
  72. char    *Unknowns[1024];
  73. int        N_Unknowns = 0;
  74.  
  75. usage()
  76. {
  77.     fprintf( stderr, "Usage: %s [-l] [-p] name ...\n", MyName );
  78.     exit( 1 );
  79. }
  80.  
  81. main( argc, argv )
  82. int        argc;
  83. char    *argv[];
  84. {
  85.     int            sock = -1;
  86.     XDR            xdr, *xdrs = NULL;
  87.  
  88.     MyName = argv[0];
  89.  
  90.     argv++;
  91.     argc--;
  92.     if( argc && argv[0][0] == '-' ) {
  93.         if( argv[0][1] == 'l' ) {
  94.             Verbose++;
  95.         } else if( argv[0][1] == 'p' ) {
  96.             SortByPrio = 1;
  97.         } else {
  98.             usage();
  99.         }
  100.         argv++;
  101.         argc--;
  102.     }
  103.  
  104.     config( MyName, (CONTEXT *)0 );
  105.     init_params();
  106.     Terse = TRUE;
  107.     Silent = TRUE;
  108.  
  109.     if( RollCall ) {
  110.         read_roster_file();
  111.     }
  112.  
  113.         /* Connect to the collector */
  114.     if( (sock = do_connect(CollectorHost, "condor_collector",
  115.                                                 COLLECTOR_PORT)) < 0 ) {
  116.         dprintf( D_ALWAYS, "Can't connect to Condor Collector\n" );
  117.         exit( 1 );
  118.     }
  119.     xdrs = xdr_Init( &sock, &xdr );
  120.     xdrs->x_op = XDR_ENCODE;
  121.  
  122.     if( Verbose ) {
  123.         get_status( argc, argv, xdrs );
  124.     } else {
  125.         get_status_lines( argc, argv, xdrs );
  126.         if( RollCall ) {
  127.             display_unknowns();
  128.             display_absent();
  129.         }
  130.     }
  131. }
  132.  
  133. get_status_lines( argc, argv, xdrs )
  134. int        argc;
  135. char    *argv[];
  136. XDR        *xdrs;
  137. {
  138.     int            i;
  139.     int            cmd;
  140.     STATUS_LINE    *line;
  141.     int            name_comp(), prio_comp();
  142.  
  143.     cmd = GIVE_STATUS_LINES;
  144.     ASSERT( xdr_int(xdrs, &cmd) );
  145.     ASSERT( xdrrec_endofrecord(xdrs,TRUE) );
  146.  
  147.     xdrs->x_op = XDR_DECODE;
  148.  
  149.     for(;;) {
  150.         line = (STATUS_LINE *)calloc( 1, sizeof(STATUS_LINE) );
  151.         if( !xdr_status_line( xdrs, line ) ) {
  152.             EXCEPT( "Can't read status line from Condor Collector" );
  153.         }
  154.         if( line->name == NULL || line->name[0] == '\0' ) {
  155.             break;
  156.         }
  157.  
  158.         if( line->state == NULL ) {
  159.             line->state = "";
  160.         }
  161.  
  162.         if( strcmp(line->state,"(DOWN)") == MATCH ) {
  163.             continue;
  164.         }
  165.  
  166.         inc_summary( line );
  167.  
  168.         if( RollCall ) {
  169.             mark_present( line->name );
  170.         }
  171.  
  172.         if( !selected(strdup(line->name),argc,argv) ) {
  173.             continue;
  174.         }
  175.         StatusLines[ N_StatusLines++ ] = line;
  176.     }
  177.  
  178.     if( SortByPrio ) {
  179.         qsort( (char *)StatusLines, N_StatusLines, sizeof(StatusLines[0]),
  180.                                                                 prio_comp );
  181.     } else {
  182.         qsort( (char *)StatusLines, N_StatusLines, sizeof(StatusLines[0]),
  183.                                                                 name_comp );
  184.     }
  185.  
  186.     print_header();
  187.     for( i=0; i<N_StatusLines; i++ ) {
  188.         display_status_line( StatusLines[i] );
  189.     }
  190.     (void)putchar( '\n' );
  191.     display_summaries();
  192. }
  193.  
  194. get_status( argc, argv, xdrs )
  195. int        argc;
  196. char    *argv[];
  197. XDR        *xdrs;
  198. {
  199.     int            cmd;
  200.     MACH_REC    *rec;
  201.  
  202.     cmd = GIVE_STATUS;
  203.     ASSERT( xdr_int(xdrs, &cmd) );
  204.     ASSERT( xdrrec_endofrecord(xdrs,TRUE) );
  205.  
  206.     xdrs->x_op = XDR_DECODE;
  207.     for(;;) {
  208.         rec = (MACH_REC *) malloc( sizeof(MACH_REC) );
  209.         if( rec == NULL ) {
  210.             EXCEPT("Out of memory");
  211.         }
  212.  
  213.         bzero( (char *)rec, sizeof(MACH_REC) );
  214.         rec->machine_context = create_context();
  215.         ASSERT( xdr_mach_rec(xdrs,rec) );
  216.         if( !rec->name || !rec->name[0] ) {
  217.             break;
  218.         }
  219.         if( !selected(strdup(rec->name),argc,argv) ) {
  220.             continue;
  221.         }
  222.         display_verbose( rec );
  223.     }
  224.     
  225. }
  226.  
  227.  
  228. selected( name, argc, argv )
  229. char    *name;
  230. int        argc;
  231. char    *argv[];
  232. {
  233.     int        i;
  234.     char    *ptr, *index();
  235.  
  236.     if( argc == 0 ) {
  237.         return 1;
  238.     }
  239.  
  240.     for( i=0; i<argc; i++ ) {
  241.         if( ptr=index(name,'.') ) {
  242.             *ptr = '\0';
  243.         }
  244.         if( strcmp(argv[i],name) == MATCH ) {
  245.             return 1;
  246.         }
  247.     }
  248.     return 0;
  249. }
  250.  
  251. display_verbose( ptr )
  252. MACH_REC    *ptr;
  253. {
  254.     printf( "name: \"%s\"\n", ptr->name );
  255.     printf( "machine_context:\n" );
  256.     display_context( ptr->machine_context );
  257.     printf( "time_stamp: %s", ctime( (time_t *)&ptr->time_stamp) );
  258.     printf( "prio: %d\n", ptr->prio );
  259.     printf( "\n" );
  260. }
  261.  
  262.  
  263. init_params()
  264. {
  265.     if( (CollectorHost = param("COLLECTOR_HOST")) == NULL ) {
  266.         EXCEPT( "COLLECTOR_HOST not specified in config file\n" );
  267.     }
  268.     RosterFile = param( "ROSTER_FILE" );
  269.     if( RosterFile ) {
  270.         RollCall = TRUE;
  271.     }
  272. }
  273.  
  274.  
  275. SetSyscalls(){}
  276.  
  277. name_comp( ptr1, ptr2 )
  278. STATUS_LINE    **ptr1, **ptr2;
  279. {
  280.     int        status;
  281.  
  282.     if( status = strcmp( (*ptr1)->arch, (*ptr2)->arch ) ) {
  283.         return status;
  284.     }
  285.  
  286.     if( status = strcmp( (*ptr1)->op_sys, (*ptr2)->op_sys ) ) {
  287.         return status;
  288.     }
  289.  
  290.     return strcmp( (*ptr1)->name, (*ptr2)->name );
  291. }
  292.  
  293. prio_comp( ptr1, ptr2 )
  294. STATUS_LINE    **ptr1, **ptr2;
  295. {
  296.     int        status;
  297.  
  298.     if( status = strcmp( (*ptr1)->arch, (*ptr2)->arch ) ) {
  299.         return status;
  300.     }
  301.  
  302.     if( status = strcmp( (*ptr1)->op_sys, (*ptr2)->op_sys ) ) {
  303.         return status;
  304.     }
  305.  
  306.     if( status = (*ptr1)->prio - (*ptr2)->prio ) {
  307.         return status;
  308.     }
  309.  
  310.     return strcmp( (*ptr1)->name, (*ptr2)->name );
  311. }
  312.  
  313. typedef struct {
  314.     char    *arch;
  315.     char    *op_sys;
  316.     int        machines;
  317.     int        jobs;
  318.     int        running;
  319. } SUMMARY;
  320.  
  321. SUMMARY        *Summary[50];
  322. int            N_Summaries;
  323. SUMMARY        Total;
  324.  
  325. inc_summary( line )
  326. STATUS_LINE    *line;
  327. {
  328.     SUMMARY    *s, *get_summary();
  329.  
  330.     s = get_summary( line );
  331.     s->machines += 1;
  332.     s->jobs += line->tot;
  333.  
  334.     Total.machines += 1;
  335.     Total.jobs += line->tot;
  336.  
  337.     if( strncmp(line->state, "Run", 3) == 0 ) {
  338.         s->running += 1;
  339.         Total.running += 1;
  340.     }
  341. }
  342.  
  343. SUMMARY *
  344. get_summary( line )
  345. STATUS_LINE    *line;
  346. {
  347.     int        i;
  348.     SUMMARY    *new;
  349.  
  350.     for( i=0; i<N_Summaries; i++ ) {
  351.         if( strcmp(Summary[i]->arch,line->arch) == MATCH &&
  352.                         strcmp(Summary[i]->op_sys,line->op_sys) == MATCH ) {
  353.             return Summary[i];
  354.         }
  355.     }
  356.  
  357.     new = (SUMMARY *)calloc( 1, sizeof(SUMMARY) );
  358.     new->arch = line->arch;
  359.     new->op_sys = line->op_sys;
  360.     Summary[ N_Summaries++ ] = new;
  361.     return new;
  362. }
  363.  
  364. display_summaries()
  365. {
  366.     int        i;
  367.  
  368.     for( i=0; i<N_Summaries; i++ ) {
  369.         display_summary( Summary[i] );
  370.     }
  371.     display_summary( &Total );
  372.  
  373. }
  374.  
  375. display_summary( s )
  376. SUMMARY        *s;
  377. {
  378.     char    tmp[256];
  379.  
  380.     if( s->arch ) {
  381.         (void)sprintf( tmp, "%s/%s", s->arch, s->op_sys );
  382.     } else {
  383.         tmp[0] = '\0';
  384.     }
  385.  
  386.     printf( "%-20s %3d machines %3d jobs %3d running\n",
  387.                     tmp, s->machines, s->jobs, s->running );
  388. }
  389.  
  390.  
  391. read_roster_file()
  392. {
  393.     FILE    *fp;
  394.     char    *ltrunc();
  395.     char    buf[1024];
  396.  
  397.     if( !RosterFile ) {
  398.         fprintf( stderr, "\"ROSTER_FILE\" not specified in config file\n" );
  399.         exit( 1 );
  400.     }
  401.  
  402.     if( (fp=fopen(RosterFile,"r")) == NULL ) {
  403.         RollCall = 0;
  404.         return;
  405.     }
  406.  
  407.     while( fgets(buf,sizeof buf,fp) ) {
  408.         add_roster_elem( ltrunc(buf) );
  409.     }
  410.     Absent = RosterLen;
  411. }
  412.  
  413. add_roster_elem( line )
  414. char    *line;
  415. {
  416.     char    *ptr;
  417.     char    *comment;
  418.  
  419.     for( ptr=line; *ptr && !isspace(*ptr); ptr++ )
  420.         ;
  421.  
  422.     if( *ptr ) {
  423.         comment = ptr + 1;
  424.         *ptr = '\0';
  425.     } else {
  426.         comment = ptr;
  427.     }
  428.     Roster[RosterLen].name = strdup( line );
  429.  
  430.     for( ptr=comment; *ptr && isspace(*ptr); ptr++ )
  431.         ;
  432.  
  433.     Roster[RosterLen].comment = strdup( ptr );
  434.     Roster[RosterLen].present = FALSE;
  435.  
  436.     RosterLen += 1;
  437. }
  438.  
  439. display_unknowns()
  440. {
  441.     int        i;
  442.  
  443.     if( N_Unknowns == 0 ) {
  444.         return;
  445.     }
  446.  
  447.     printf( "\n" );
  448.     if( N_Unknowns == 1 ) {
  449.         printf(
  450.         "The following  machine is present, but not on the roster...\n");
  451.     } else {
  452.         printf(
  453.         "The following %d machines are present, but not on the roster...\n",
  454.         N_Unknowns );
  455.     }
  456.  
  457.     for( i=0; i<N_Unknowns; i++ ) {
  458.         printf( "%s\n", Unknowns[i] );
  459.     }
  460. }
  461.  
  462. display_absent()
  463. {
  464.     int        i;
  465.  
  466.     printf( "\n" );
  467.     if( Absent == 0 ) {
  468.         printf( "All machines on the roster are present\n" );
  469.         return;
  470.     }
  471.         
  472.     if( Absent == 1 ) {
  473.         printf( "The following machine is absent...\n" );
  474.     } else {
  475.         printf( "The following %d machines are absent...\n", Absent );
  476.     }
  477.  
  478.     for( i=0; i<RosterLen; i++ ) {
  479.         if( !Roster[i].present ) {
  480.             printf( "%-15s %s\n", Roster[i].name, Roster[i].comment );
  481.         }
  482.  
  483.     }
  484. }
  485.  
  486. mark_present( name )
  487. char    *name;
  488. {
  489.     int        i;
  490.     char    *ptr;
  491.  
  492.     if( ptr=index(name,'.') ) {
  493.         *ptr = '\0';
  494.     }
  495.  
  496.     for( i=0; i<RosterLen; i++ ) {
  497.         if( strcmp(name,Roster[i].name) == 0 ) {
  498.             Roster[i].present = TRUE;
  499.             Absent -= 1;
  500.             return;
  501.         }
  502.     }
  503.     Unknowns[N_Unknowns] = strdup( name );
  504.     N_Unknowns += 1;
  505. }
  506.