static char dqs_c_qidle_rcsid[]="$Id: dqs_c_qidle.c,v 1.1.1.1 1998/08/18 14:39:11 green Exp $";

/*----------------------------------------------------
 * dqs_c_qidle.c Neil Lincoln  Fri  Jan 12 11:20:16 1996
 *
 * Copyright 1993
 *
 * SUPER COMPUTER COMPUTATIONS RESEARCH INSTITUTE
 *            FLORIDA STATE UNIVERSITY
 *
 *
 * SCRI representatives make no claims about the
 * suitability of this software for any purpose.
 * It is provided "as is" without express or
 * implied warranty.
 *
 * $Log: dqs_c_qidle.c,v $
 * Revision 1.1.1.1  1998/08/18 14:39:11  green
 * DQS 3.2.0.5 WIP Import
 *
 * Revision 1.1.1.1  1997/04/10 15:10:31  green
 * DQS 3.1.3.4.1 Distribution
 *
 * Revision 3.6  1996/08/03 14:08:53  nrl
 * fixed problem in qconf -mq where several fields were not getting
 * updated
 *
 * Revision 3.5  1996/06/27  01:55:43  nrl
 * changes to accomodate osf gcc
 *
 * Revision 3.4  1996/03/24  20:00:03  nrl
 * fixed a problem.. QIDLE cannot un-SUBORDINATE a queue
 *
 * Revision 3.3  1996/03/22  21:45:03  nrl
 * updates new utilities
 *
 * Revision 3.2  1996/03/22  04:20:01  nrl
 * Added error cataloguing number to all routines
 *
 * Revision 3.1  1996/03/21  20:45:28  nrl
 * adding new utilities and moved qidle to mainline code
 *
 *--------------------------------------------------*/


#include "h.h"
#include "def.h"
#include "dqs.h"
#include "struct.h"
#include "func.h"
#include "globals.h"
#include "dqs_errno.h"

/************************************************************************/
void dqs_c_qidle(sfd,request_head)
     int           sfd;
     dqs_list_type **request_head;
     
     /*
       dqs_c_qidle is used solely by the qmaster and provides services
       to the qidle ancillary.
     */
     
{
  
  int                found;
  int                status;
  char               *cp;
  u_long32           i;
  string             str;
  dqs_list_type      *lp;
  dqs_list_type      *lp2;
  dqs_list_type      listel;
  dqs_list_type      *request_list;
  dqs_list_type      *reply_head=NULL;
  dqs_queue_type     *queue_ptr;
  struct sockaddr_in cli_addr;
  
  DENTER((DQS_EVENT,"dqs_c_qidle"));
  
  request_list= *request_head;
  
  if ((reply_head=dqs_locate_tid(request_list->tid)))
    {  /* this transaction has already occurred */ 
      INFO((DQS_EVENT,"DQS_ERROR_0135 TRANSACTION ALREADY OCCURRED"));
      *request_head=dqs_free_list(*request_head);
      if ((sfd=dqs_send_list(NULL,NULL,sfd,reply_head))<0)
	{
	  DEXITE;
	  return;
	}
      dqs_close_sfd(sfd);
      DEXIT;
      return;
    }
  
  DPRINTF((DQS_EVENT,"------------------------------------------------------"));
  
  switch(request_list->type)
    {
    case SIGNAL_QUEUE_REQUEST:
      DPRINTF((DQS_EVENT,"===>QIDLE:"));
      
      bzero((char *)&listel,sizeof(listel));
      listel.type=TRUE;
      lp=Queue_head;
      
      while (lp)
	{
	  /*  affect all queues for this host  */
	  if(!strcmp(lp->queue->qhostname, request_list->job->dqs_o_host) ){
	    
	    switch(request_list->job->suspend_enable)  {
	      
	    case SUSPENDED:
	      
	      if (dqs_signal_queue(DQS_SIGSTOP,lp->queue,0)) {
		NAK((ACK_EVENT,"warning: %s unable to force a SUSPENDED state remote sync of the queue \"%s\"",
		     request_list->user,lp->queue->qname));
		WARNING((DQS_EVENT,"DQS_ERROR_0136 %s",ACK_EVENT));
	      }
	      else {
		NAK((ACK_EVENT,"warning: %s forced a SUSPENDED state remote sync of the queue \"%s\"",
		     request_list->user,lp->queue->qname));
		WARNING((DQS_EVENT,"DQS_ERROR_0137 %s",ACK_EVENT));
	      }
	      
	      CLEARBIT(RUNNING,lp->queue->state); /* JIC */
	      SETBIT(SUSPENDED,lp->queue->state);
	      dqs_write_queue_to_disk(lp->queue);
	      
	      break;
	      
            case RUNNING:
	      
	      
	      if (dqs_signal_queue(DQS_SIGCONT,lp->queue,0)) {
		NAK((ACK_EVENT,"warning: %s unable to force a RUNNING state remote sync of the queue \"%s\"",
		     request_list->user,lp->queue->qname));
		WARNING((DQS_EVENT,"DQS_ERROR_0138 %s",ACK_EVENT));
	      }
	      else{
		NAK((ACK_EVENT,"warning: %s forced a RUNNING state remote sync of the queue \"%s\"",
		     request_list->user,lp->queue->qname));
		WARNING((DQS_EVENT,"DQS_ERROR_0139 %s",ACK_EVENT));
	      }
	      if(VALID(SUBORDINATED, lp->queue->state) ){
		break; /* qidle cannot un-subordinate a queue */
	      }
	      CLEARBIT(SUSPENDED,lp->queue->state); /* JIC */
	      CLEARBIT(SUBORDINATED,lp->queue->state); /* JIC */                              
	      SETBIT(RUNNING,lp->queue->state);
	      dqs_write_queue_to_disk(lp->queue);
	      break;
	      
	    default:
	      NAK((ACK_EVENT,"error: unknown qmod action request %d",request_list->job->suspend_enable));
	      INFO((DQS_EVENT,"DQS_ERROR_0140 %s",ACK_EVENT));
	      break;
	      
	    }
	  }  /*   susupend or unsuspend for this host  */ 
	  lp=lp->next;
	}
      if (!reply_head)
	{
	  NAK((ACK_EVENT,"error: no suitable queues"));
	}
      break;
      
      /*------------------------------------------------------*/
    default:
      NAK((ACK_EVENT,"error: unknown list type %d",request_list->type));
      INFO((DQS_EVENT,"DQS_ERROR_0141 %s",ACK_EVENT));
      break;
    }
  
 dqs_c_qidle_end:
  
  reply_head->tid=request_list->tid;
  dqs_save_tid(reply_head,QIDLE);
  request_list->tid=NULL;
  
  *request_head=dqs_free_list(*request_head);
  
  if ((sfd=dqs_send_list(NULL,NULL,sfd,reply_head))<0)
    {
      DEXITE;
      return;
    }
  
  dqs_close_sfd(sfd);
  
  DEXIT;
  return;
  
}


