static char dqs_c_qidle_rcsid[]="$Id: dqs_c_qidle.c,v 1.1.1.1 1997/04/10 15:10:31 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  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;
     
}


