/****** qmaster/sge_thread_scheduler/event_update_func() **************************
*  NAME
*     event_update_func() -- 
*
*  SYNOPSIS
*     void event_update_func(lList **alpp, lList *event_list)
*
*  FUNCTION
*
*  INPUTS
*     lList **alpp - answer list
*     lList *event_list - a report list, the event are stored in REP_list
*
*  RESULT
*     void - none
*
*  NOTES
*     MT-NOTE: is MT safe. 
*
*******************************************************************************/
void event_update_func(u_long32 ec_id, lList **alpp, lList *event_list) 
{
   DENTER(TOP_LAYER, "event_update_func");

   sge_mutex_lock("event_control_mutex", SGE_FUNC, __LINE__, &Scheduler_Control.mutex);  
   
   if (Scheduler_Control.new_events != NULL) {
      lList *events = NULL;
      lXchgList(lFirst(event_list), REP_list, &(events));
      lAddList(Scheduler_Control.new_events, &events);
   } else {
      lXchgList(lFirst(event_list), REP_list, &(Scheduler_Control.new_events));
   }   
   
   Scheduler_Control.triggered = true;

   DPRINTF(("EVENT UPDATE FUNCTION event_update_func() HAS BEEN TRIGGERED\n"));

   pthread_cond_signal(&Scheduler_Control.cond_var);

   sge_mutex_unlock("event_control_mutex", SGE_FUNC, __LINE__, &Scheduler_Control.mutex);


   DRETURN_VOID;
}
Beispiel #2
0
/*-------------------------------------------------------------------------*/
static void qmonCalendarOk(Widget w, XtPointer cld, XtPointer cad)
{
   lList *cal = NULL;
   lList *alp;
   lEnumeration *what;
   Boolean status = False;
   XmString xcalname = NULL;
   StringConst calname = NULL;

   DENTER(GUI_LAYER, "qmonCalendarOk");
   /*
   ** get the contents of the dialog fields here,
   ** build the cull list and send gdi request
   ** decalnding on success of gdi request close the dialog or stay ocaln
   */
   cal = lCreateElemList("CALENDAR_ADD", CAL_Type, 1);
   
   if (cal) {
      if (qmonCalendarGetAsk(lFirst(cal))) {
         calname = (StringConst)lGetString(lFirst(cal), CAL_name);
         /*
         ** gdi call 
         */
         what = lWhat("%T(ALL)", CAL_Type);
         
         if (add_mode) {
            alp = qmonAddList(SGE_CAL_LIST, 
                              qmonMirrorListRef(SGE_CAL_LIST),
                              CAL_name, &cal, NULL, what);
         }
         else {
            alp = qmonModList(SGE_CAL_LIST, 
                              qmonMirrorListRef(SGE_CAL_LIST),
                              CAL_name, &cal, NULL, what);
         }

         if (lFirst(alp) && lGetUlong(lFirst(alp), AN_status) == STATUS_OK)
            status = True;

         qmonMessageBox(w, alp, 0);

         if (status) {
            XtUnmanageChild(cal_ask_layout);
            updateCalendarList();
            /*
            ** select the modified or added Calendar
            */
            xcalname = XmtCreateXmString(calname);
            XmListSelectItem(cal_names, xcalname, True);
            XmStringFree(xcalname);
         }
         lFreeWhat(&what);
         lFreeList(&cal);
         lFreeList(&alp);
      }
   }


   DEXIT;
}
Beispiel #3
0
/*-------------------------------------------------------------------------*/
static void qmonSchedOk(Widget w, XtPointer cld, XtPointer cad)
{
   lList *scl = NULL;
   lListElem *sep = NULL;
   lEnumeration *what = NULL;
   lList *alp = NULL;
   Boolean status = False;

   DENTER(GUI_LAYER, "qmonSchedOk");

   /*
   ** get the contents of the dialog fields here,
   ** build the cull list and send gdi request
   */
   qmonMirrorMultiAnswer(SC_T, &alp);
   if (alp) {
      qmonMessageBox(w, alp, 0);
      lFreeList(&alp);
      DEXIT;
      return;
   }


   scl = qmonMirrorList(SGE_SC_LIST);
   sep = lFirst(scl); 


   if (qmonSchedGet(sep)) {

      if (rmon_mlgetl(&RMON_DEBUG_ON, GUI_LAYER) & INFOPRINT) {
         printf("___SCHEDULER_CONF________________________\n");
         lWriteListTo(scl, stdout);
         printf("_______________________________________\n");
      }
      /*
      ** gdi call 
      */
      what = lWhat("%T(ALL)", SC_Type);

      alp = qmonModList(SGE_SC_LIST, qmonMirrorListRef(SGE_SC_LIST),
                           0, &scl, NULL, what);

      
      if (lFirst(alp) && lGetUlong(lFirst(alp), AN_status) == STATUS_OK)
         status = True;

      qmonMessageBox(qmon_sconf, alp, 0);

      lFreeWhat(&what);
      lFreeList(&alp);
   }

   if (status)
      XtUnmanageChild(qmon_sconf);

   DEXIT;
}
Beispiel #4
0
/****** qmaster/setup_qmaster/sge_setup_job_resend() ***************************
*  NAME
*     sge_setup_job_resend() -- Setup job resend events.
*
*  SYNOPSIS
*     void sge_setup_job_resend(void)
*
*  FUNCTION
*     Register a job resend event for each job or array task which does have a
*     'JTRANSFERING' status.
*
*  INPUTS
*     void - none
*
*  RESULT
*     void - none
*
*  NOTES
*     MT-NOTE: sge_setup_job_resend() is not MT safe
*
*******************************************************************************/
void sge_setup_job_resend(void)
{
    lListElem *job = NULL;
    object_description *object_base = object_type_get_object_description();

    DENTER(TOP_LAYER, "sge_setup_job_resend");

    job = lFirst(*object_base[SGE_TYPE_JOB].list);

    while (NULL != job)
    {
        lListElem *task;
        u_long32 job_num;

        job_num = lGetUlong(job, JB_job_number);

        task = lFirst(lGetList(job, JB_ja_tasks));

        while (NULL != task)
        {
            if (lGetUlong(task, JAT_status) == JTRANSFERING)
            {
                lListElem *granted_queue, *qinstance, *host;
                const char *qname;
                u_long32 task_num, when;
                te_event_t ev;

                task_num = lGetUlong(task, JAT_task_number);

                granted_queue = lFirst(lGetList(task, JAT_granted_destin_identifier_list));

                qname = lGetString(granted_queue, JG_qname);

                qinstance = cqueue_list_locate_qinstance(*object_base[SGE_TYPE_CQUEUE].list, qname);

                host = host_list_locate(*object_base[SGE_TYPE_EXECHOST].list, lGetHost(qinstance, QU_qhostname));

                when = lGetUlong(task, JAT_start_time);

                when += MAX(load_report_interval(host), MAX_JOB_DELIVER_TIME);

                ev = te_new_event((time_t)when, TYPE_JOB_RESEND_EVENT, ONE_TIME_EVENT, job_num, task_num, "job-resend_event");
                te_add_event(ev);
                te_free_event(&ev);

                DPRINTF(("Did add job resend for "sge_u32"/"sge_u32" at %d\n", job_num, task_num, when));
            }

            task = lNext(task);
        }

        job = lNext(job);
    }

    DEXIT;
    return;
} /* sge_setup_job_resend() */
Beispiel #5
0
/****** sgeobj/var/var_list_split_prefix_vars() *******************************
*  NAME
*     var_list_split_prefix_vars() -- split a list of variables 
*
*  SYNOPSIS
*     void var_list_split_prefix_vars(lList **varl, 
*                                     lList **pefix_vars, 
*                                     const char *prefix) 
*
*  FUNCTION
*     Move all variable elements form "varl" to "pefix_vars" which 
*     begin with "prefix". *pefix_vars will be created if is does not
*     exist.
*
*  INPUTS
*     lList **varl        - VA_Type list 
*     lList **pefix_vars - pointer to VA_Type list 
*     const char *prefix - string (e.g. VAR_PREFIX) 
*
*  RESULT
*     void - None
*
*  SEE ALSO
*     sgeobj/var/var_list_remove_prefix_vars()
******************************************************************************/
void var_list_split_prefix_vars(lList **varl, 
                                lList **pefix_vars, 
                                const char *prefix)
{
   int prefix_len = strlen(prefix);
   lListElem *var_elem = NULL;
   lListElem *next_var_elem = NULL;

   DENTER(TOP_LAYER, "var_list_remove_prefix_vars");
   next_var_elem = lFirst(*varl);
   while((var_elem = next_var_elem)) {
      const char *prefix_name = lGetString(var_elem, VA_variable);
      next_var_elem = lNext(var_elem);

      if (!strncmp(prefix_name, prefix, prefix_len)) {
         lListElem *dechained_elem = lDechainElem(*varl, var_elem);

         if (*pefix_vars == NULL) {
            *pefix_vars = lCreateList("", VA_Type);
         }

         lAppendElem(*pefix_vars, dechained_elem);
      }
   }
   DEXIT;
   return;
}
static void schedd_mes_find_others(lListElem *tmp_sme, lList *job_list, int ignore_category)
{
   if (tmp_sme && job_list) {
      lListElem *message_elem = NULL;  /* MES_Type */
      lRef category = NULL;            /* Category pointer (void*) */
      lList *jid_cat_list = NULL;      /* ULNG */
      lList *message_list = lGetList(tmp_sme, SME_message_list);

      /*
       * Here we have a list of message elements where each 
       * MES_job_number_list contains only one id.
       * We have to find the other jobs (jids) which have the same category.
       */
      for_each(message_elem, message_list) {
         lList *jid_list = lGetList(message_elem, MES_job_number_list);
         u_long32 jid;
         lRef jid_category; 
         jid = lGetUlong(lFirst(jid_list), ULNG_value);
         jid_category = schedd_mes_get_category(jid, job_list);

         /*
          * Initialize jid_cat_list if not initialized
          * or if category differs from the last run
          */
         if (category != jid_category || ignore_category) {
            jid_cat_list = schedd_mes_get_same_category_jids(jid_category,
                                                             job_list,
                                                             ignore_category);
            category = jid_category;
            lSetList(message_elem, MES_job_number_list, jid_cat_list);
         } else {
            lSetList(message_elem, MES_job_number_list,
                     lCopyList("", jid_cat_list));
         }
      }
/************************************************************
  sge_del_sharetree - Master code

  Delete the sharetree
 ************************************************************/
int sge_del_sharetree(
sge_gdi_ctx_class_t *ctx,
lList **lpp,    /* list to change */
lList **alpp,
char *ruser,
char *rhost 
) {
   DENTER(TOP_LAYER, "sge_del_sharetree");

   if (!*lpp || !lFirst(*lpp)) {
      ERROR((SGE_EVENT, MSG_SGETEXT_DOESNOTEXIST_S, MSG_OBJ_SHARETREE));
      answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EEXIST;
   }

   sge_event_spool(ctx,
                   alpp, 0, sgeE_NEW_SHARETREE, 
                   0, 0, NULL, NULL, NULL,
                   NULL, NULL, NULL, true, true);

   lFreeList(lpp);

   INFO((SGE_EVENT, MSG_SGETEXT_REMOVEDLIST_SSS, ruser, rhost, MSG_OBJ_SHARETREE));
   answer_list_add(alpp, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO);

   DEXIT;
   return STATUS_OK;
}
Beispiel #8
0
lListElem *cuser_get_via_gdi(sge_gdi_ctx_class_t *ctx, lList **answer_list, const char *name) 
{
   lListElem *ret = NULL;

   DENTER(TOP_LAYER, "cuser_get_via_gdi");

   if (name != NULL) {
      lList *gdi_answer_list = NULL;
      lEnumeration *what = NULL;
      lCondition *where = NULL;
      lList *cuser_list = NULL;

      what = lWhat("%T(ALL)", CU_Type);
      where = lWhere("%T(%I==%s)", CU_Type, CU_name, name);
      gdi_answer_list = ctx->gdi(ctx, SGE_USER_MAPPING_LIST, SGE_GDI_GET, 
                                &cuser_list, where, what);
      lFreeWhat(&what);
      lFreeWhere(&where);

      if (!answer_list_has_error(&gdi_answer_list)) {
         ret = lFirst(cuser_list);
      } else {
         answer_list_replace(answer_list, &gdi_answer_list);
      }
   } 

   DRETURN(ret);
}
sge_callback_result
job_schedd_info_update_master_list(sge_evc_class_t *evc, object_description *object_base, sge_object_type type, 
                                   sge_event_action action, lListElem *event, void *clientdata)
{
   lList **list = NULL;
   const lDescr *list_descr = NULL;

   lList *data_list;
   lListElem *ep = NULL;
   
   DENTER(TOP_LAYER, "job_schedd_info_update_master_list");

   list = sge_master_list(object_base, type); 
   list_descr = lGetListDescr(lGetList(event, ET_new_version));

   /* We always update the whole list (consisting of one list element) */
   lFreeList(list);

   if((data_list = lGetList(event, ET_new_version)) != NULL) {
      if((ep = lFirst(data_list)) != NULL) {
         ep = lDechainElem(data_list, ep);
      }
   }

   /* if neccessary, create list and copy schedd info */
   if(ep != NULL) {
      *list = lCreateList("job schedd info", list_descr);
      lAppendElem(*list, ep);
   }

   DEXIT;
   return SGE_EMA_OK;
}
/****** Eventmirror/schedd_conf/schedd_conf_update_master_list() ***************
*  NAME
*     schedd_conf_update_master_list() -- update the scheduler configuration
*
*  SYNOPSIS
*     bool 
*     schedd_conf_update_master_list(sge_object_type type, 
*                                    sge_event_action action,
*                                    lListElem *event, void *clientdata)
*
*  FUNCTION
*     Update the global master list of scheduler configurations
*     based on an event.
*     The function is called from the event mirroring interface.
*     The list only contains one element that is replaced when a
*     modify event arrives.
*
*  INPUTS
*     sge_object_type type     - event type
*     sge_event_action action - action to perform
*     lListElem *event        - the raw event
*     void *clientdata        - client data
*
*  RESULT
*     bool - true, if update is successfull, else false
*
*  NOTES
*     The function should only be called from the event mirror interface.
*
*  SEE ALSO
*     Eventmirror/--Eventmirror
*******************************************************************************/
sge_callback_result
schedd_conf_update_master_list(sge_evc_class_t *evc, object_description *object_base, sge_object_type type, 
                               sge_event_action action, lListElem *event, void *clientdata)
{
   lList *list = NULL;
   lList *answer_list = NULL;
   lDescr *list_descr;

   lList *data_list;
   lListElem *ep = NULL;

   DENTER(TOP_LAYER, "schedd_conf_update_master_list");

   list_descr = SC_Type;

   if ((data_list = lGetList(event, ET_new_version)) != NULL) {
      if ((ep = lFirst(data_list)) != NULL) {
         ep = lDechainElem(data_list, ep);
      }
   }

   /* if neccessary, create list and copy schedd info */
   if (ep != NULL) {
      list = lCreateList("schedd config", list_descr);
      lAppendElem(list, ep);
   }

   if (!sconf_set_config(&list, &answer_list)) {
      lFreeList(&list);
      answer_list_output(&answer_list);
   }

   DEXIT;
   return SGE_EMA_OK;
}
/****** SCHEDD/remove_immediate_jobs()******************************************
*  NAME
*     remove_immediate_jobs() -- test for and remove immediate jobs which can't
*                                be scheduled
*
*  SYNOPSIS
*     int remove_immediate_jobs(lList *pending_job_list,
                                lList *running_job_list, order_t *orders)
*
*  FUNCTION
*     Goes through all jobs in the pending list to see if any are immediate and
*     not idle.  If any are, they are removed.  This is done by generating an
*     order of type ORT_remove_immediate_job.  If any array jobs are removed,
*     the running list is checked for tasks belonging to the job, which are
*     also removed.  This is done by removing the ORT_start_job orders and
*     adding an order of type ORT_remove_immediate_job.
*
*  INPUTS
*     lList *pending_job_list   - The list of pending jobs for this scheduler
*                                 pass (JB_Type)
*     lList *running_job_list   - The list of running jobs for this scheduler
*                                 pass (JB_Type)
*     order_t *orders           - The order structure for this scheduler pass
*
*  RESULT
*     int - Error code: 0 = OK, 1 = Errors -- always returns 0
*
*  NOTES
*     MT-NOTE: remove_immediate_jobs() is MT safe
*
*******************************************************************************/
int remove_immediate_jobs(lList *pending_job_list, lList *running_job_list, order_t *orders) 
{
   lListElem *next_job, *job, *ep; 
   lList* lp;

   DENTER (TOP_LAYER, "remove_immediate_jobs");

   next_job = lFirst (pending_job_list);
   
   while ((job = next_job)) {
      lCondition *where = NULL;
      next_job = lNext(job);
      
      /* skip non immediate .. */
      if (!JOB_TYPE_IS_IMMEDIATE(lGetUlong(job, JB_type))) {
         continue;
      }

      /* .. and non idle jobs */
      if ((lp = lGetList(job, JB_ja_tasks)) && 
            (ep = lFirst(lp)) && 
            lGetUlong(ep, JAT_status)==JIDLE) {
         continue;    
      }

      /* Prepare search condition for running list */
      where = lWhere("%T(%I==%u)", JB_Type, JB_job_number, lGetUlong(job, JB_job_number));
      
      /* Remove the job from the pending list */
      remove_immediate_job(pending_job_list, job, orders, 0);
      
      /* If the job also exists in the running list, we need to remove it there
       * as well since array jobs are all or nothing. */
      if ((job = lFindFirst(running_job_list, where)) != NULL) {
         remove_immediate_job(running_job_list, job, orders, 1);
      }
      
      lFreeWhere(&where);
   }

   DEXIT;
   return 0;
}
Beispiel #12
0
/*-------------------------------------------------------------------------*/
void qmonSetCE_Type(
Widget w,
lList *lp,
int full 
) {
   lListElem *ep;
   int row;
   int max_rows;
   const char *ce_entry[CE_MAX];
   int i;
   
   DENTER(GUI_LAYER, "qmonSetCE_Type");
   
   XtVaGetValues(w, XmNrows, &max_rows, NULL);
   
   /* clear the area */
   XtVaSetValues(w, XmNcells, NULL, NULL);
   
   for (ep = lFirst(lp), row = 0; ep; ep = lNext(ep), row++) {
      if (row == max_rows) {
         XbaeMatrixAddRows(w, 
                           max_rows, 
                           NULL,       /* empty rows  */
                           NULL,       /* no lables   */
                           NULL,       /* no different colors */
                           1);         /* we add 1 row */
         max_rows++;
      }
      if (getCE_TypeValues(ep, ce_entry)) {
         if (full) {
            for (i=0; i<CE_MAX; i++) {
               /* FIX_CONST_GUI */
               XbaeMatrixSetCell(w, row, i, 
                  ce_entry[i] ? (String)ce_entry[i] : "");
            }
         }
         else {
            /* FIX_CONST_GUI */
            XbaeMatrixSetCell(w, row, 0, 
               ce_entry[CE_NAME] ? (String)ce_entry[CE_NAME] : "");
            /* FIX_CONST_GUI */
            XbaeMatrixSetCell(w, row, 1, 
               ce_entry[CE_TYPE] ? (String)ce_entry[CE_TYPE] : "");
            /* FIX_CONST_GUI */
            XbaeMatrixSetCell(w, row, 2, 
               ce_entry[CE_RELOP] ? (String)ce_entry[CE_RELOP] : "");
         }
      }
      else
         DPRINTF(("qmonSetCE_Type failure\n"));
   }
       
   DEXIT;
}
Beispiel #13
0
/****** cull/db/lSplit() ******************************************************
*  NAME
*     lSplit() -- Splits a list into two list 
*
*  SYNOPSIS
*     int lSplit(lList **slp, lList **ulp, const char *ulp_name, 
*                const lCondition *cp) 
*
*  FUNCTION
*     Unchains the list elements from the list 'slp' NOT fullfilling
*     the condition 'cp' and returns a list containing the 
*     unchained elements in 'ulp' 
*
*  INPUTS
*     lList **slp          - source list pointer 
*     lList **ulp          - unchained list pointer 
*     const char *ulp_name - 'ulp' list name 
*     const lCondition *cp - selects rows within 'slp' 
*
*  RESULT
*     int - error status
*         0 - OK
*        -1 - Error 
******************************************************************************/
int lSplit(lList **slp, lList **ulp, const char *ulp_name, 
           const lCondition *cp) 
{

   lListElem *ep, *next;
   int has_been_allocated = 0;

   DENTER(TOP_LAYER, "lSplit");

   /*
      iterate through the source list call lCompare and chain all elems
      that don't fullfill the condition into a new list.
    */
   if (!slp) {
      DEXIT;
      return -1;
   }

   for (ep = lFirst(*slp); ep; ep = next) {
      next = ep->next;          /* this is important, cause the elem is dechained */

      if (!lCompare(ep, cp)) {
         if (ulp && !*ulp) {
            *ulp = lCreateList(ulp_name ? ulp_name : "ulp", (*slp)->descr);
            if (!*ulp) {
               DEXIT;
               return -1;
            }
            has_been_allocated = 1;
         }
         if (ulp) {
            ep = lDechainElem(*slp, ep);
            lAppendElem(*ulp, ep);
         } else {
            lRemoveElem(*slp, &ep);
         }
      }
   }

   /* if no elements remain, free the list and return NULL */
   if (*slp && lGetNumberOfElem(*slp) == 0) {
      lFreeList(slp);
   }
   if (has_been_allocated && *ulp && lGetNumberOfElem(*ulp) == 0) {
      lFreeList(ulp);
   }

   DEXIT;
   return 0;
}
Beispiel #14
0
/****** sgeobj/report/job_report_init_from_job() *****************************
*  NAME
*     job_report_init_from_job() -- initialize job report 
*
*  SYNOPSIS
*     void job_report_init_from_job(lListElem *job_report, 
*                                   const lListElem *job, 
*                                   const lListElem *ja_task, 
*                                   const lListElem *pe_task) 
*
*  FUNCTION
*     Initialize "job_report" from the attributes obtained from
*     "job", "ja_task" and "pe_task". 
*
*  INPUTS
*     lListElem *job_report    - JR_Type object
*     const lListElem *job     - JB_Type object
*     const lListElem *ja_task - JAT_Type object 
*     const lListElem *pe_task - PET_Type object 
******************************************************************************/
void job_report_init_from_job(lListElem *job_report, 
                              const lListElem *job, 
                              const lListElem *ja_task, 
                              const lListElem *pe_task) 
{
   u_long32 job_id = lGetUlong(job, JB_job_number);
   u_long32 ja_task_id = lGetUlong(ja_task, JAT_task_number);
   lListElem *queue = NULL;   /* QU_Type */

   DENTER(TOP_LAYER, "job_report_init_from_job");

   lSetUlong(job_report, JR_job_number, job_id);
   lSetUlong(job_report, JR_ja_task_number, ja_task_id);

   if (pe_task != NULL) {
      lSetString(job_report, JR_pe_task_id_str, lGetString(pe_task, PET_id));
      queue = lFirst(lGetList(pe_task, PET_granted_destin_identifier_list));
   } else {
      queue = lFirst(lGetList(ja_task, JAT_granted_destin_identifier_list));
   }

   if (lGetUlong(ja_task, JAT_status) == JSLAVE){
      if (pe_task == NULL) {
         lSetUlong(job_report, JR_state, JSLAVE);
      } else {
         lSetUlong(job_report, JR_state, JWRITTEN);
      }
   } else {
      lSetUlong(job_report, JR_state, JWRITTEN);
   }

   if (queue != NULL) {
      lSetString(job_report, JR_queue_name, lGetString(queue, JG_qname));
   }

   DEXIT;
}
/****** Eventmirror/sharetree/sharetree_update_master_list() *******************
*  NAME
*     sharetree_update_master_list() -- update the master sharetree list
*
*  SYNOPSIS
*     bool 
*     sharetree_update_master_list(sge_object_type type, sge_event_action action,
*                                  lListElem *event, void *clientdata)
*
*  FUNCTION
*     Update the global master list for the sharetree
*     based on an event.
*     The function is called from the event mirroring interface.
*     Sharetree events always contain the whole sharetree, that
*     replaces an existing sharetree in the master list.
*
*  INPUTS
*     sge_object_type type     - event type
*     sge_event_action action - action to perform
*     lListElem *event        - the raw event
*     void *clientdata        - client data
*
*  RESULT
*     bool - true, if update is successfull, else false
*
*  NOTES
*     The function should only be called from the event mirror interface.
*
*  SEE ALSO
*     Eventmirror/--Eventmirror
*******************************************************************************/
sge_callback_result
sharetree_update_master_list(sge_evc_class_t *evc, object_description *object_base, sge_object_type type, sge_event_action action,
                             lListElem *event, void *clientdata)
{
   lList **list = NULL;
   lList *src = NULL;

   DENTER(TOP_LAYER, "sharetree_update_master_list");

   /* remove old share tree */
   list = sge_master_list(object_base, type); /*<== need update */
   lFreeList(list);
   

   if ((src = lGetList(event, ET_new_version))) {
      
      /* install new one */
      *list = lCreateList("share tree", lGetElemDescr(lFirst(lGetList(event, ET_new_version))));
      lAppendElem(*list, lDechainElem(src, lFirst(src)));
   }

   DEXIT;
   return SGE_EMA_OK;
}
Beispiel #16
0
static sge_callback_result
analyze_jatask_event(sge_evc_class_t *evc, object_description *object_base,sge_object_type type, 
                     sge_event_action action, lListElem *event, void *clientdata)
{
   char buffer[1024];
   dstring buffer_wrapper;

   sge_dstring_init(&buffer_wrapper, buffer, sizeof(buffer));
   
   if (lGetPosViaElem(event, ET_type, SGE_NO_ABORT) >= 0) {
      u_long32 type = lGetUlong(event, ET_type);

      if (type == sgeE_JATASK_MOD) { 
         lList *jat = lGetList(event,ET_new_version);
         lListElem *ep = lFirst(jat);
         u_long job_status = lGetUlong(ep, JAT_status);
         int task_running = (job_status==JRUNNING || job_status==JTRANSFERING);
         if (task_running) {
         }
      }

      if (type == sgeE_JOB_FINAL_USAGE) { 
      }

      if (type == sgeE_JOB_ADD) { 
         /* lList *jat = lGetList(event,ET_new_version);
         u_long job_id  = lGetUlong(event, ET_intkey);
         u_long task_id = lGetUlong(event, ET_intkey2);
         lListElem *ep = lFirst(jat); */
      }

      if (type == sgeE_JOB_DEL) { 
         qevent_trigger_scripts(QEVENT_JB_END, qevent_get_option_struct(), event);
      }

      if (type == sgeE_JATASK_DEL) { 
         qevent_trigger_scripts(QEVENT_JB_TASK_END,qevent_get_option_struct() , event);
      }


   }
   /* create a callback error to test error handling */
   if(type == SGE_TYPE_GLOBAL_CONFIG) {
      return SGE_EMA_FAILURE;
   }
   
   return SGE_EMA_OK;
}
Beispiel #17
0
/*-------------------------------------------------------------------------*/
void qmonPopupSchedConfig(Widget w, XtPointer cld, XtPointer cad)
{
   Widget shell;
   lList *scl = NULL;
   lListElem *sep = NULL;
   lList *alp = NULL;

   DENTER(TOP_LAYER, "qmonPopupSchedConfig");

   /* set busy cursor */
   XmtDisplayBusyCursor(w);

   if (!qmon_sconf) {
      shell = XmtGetTopLevelShell(w);
      qmon_sconf = qmonCreateSchedConfig(shell);
      XmtAddDeleteCallback(shell, XmDO_NOTHING, 
                              qmonSchedCancel, NULL);
   } 
   qmonMirrorMultiAnswer(SC_T, &alp);
   if (alp) {
      qmonMessageBox(w, alp, 0);
      lFreeList(&alp);
      /* set default cursor */
      XmtDisplayDefaultCursor(w);
      DEXIT;
      return;
   }

   scl = qmonMirrorList(SGE_SC_LIST);
   sep = lFirst(scl);
   qmonSchedSet(sep);
   XSync(XtDisplay(qmon_sconf), 0);
   XmUpdateDisplay(qmon_sconf);

   XtManageChild(qmon_sconf);
   XRaiseWindow(XtDisplay(XtParent(qmon_sconf)), 
                  XtWindow(XtParent(qmon_sconf)));

   /* set default cursor */
   XmtDisplayDefaultCursor(w);

   DEXIT;
}
Beispiel #18
0
/****** sgeobj/var/var_list_remove_prefix_vars() ******************************
*  NAME
*     var_list_remove_prefix_vars() -- remove vars with certain prefix 
*
*  SYNOPSIS
*     void var_list_remove_prefix_vars(lList **varl, 
*                                      const char *prefix) 
*
*  FUNCTION
*     Remove all entries from "varl" where the name
*     beginns with "prefix" 
*
*  INPUTS
*     lList **varl       - VA_Type list 
*     const char *prefix - prefix string (e.g. VAR_PREFIX) 
*
*  SEE ALSO
*     sgeobj/var/var_list_remove_prefix_vars()
******************************************************************************/
void var_list_remove_prefix_vars(lList **varl, const char *prefix)
{
   int prefix_len = strlen(prefix);
   lListElem *var_elem = NULL;
   lListElem *next_var_elem = NULL;

   DENTER(TOP_LAYER, "var_list_remove_prefix_vars");
   next_var_elem = lFirst(*varl);
   while((var_elem = next_var_elem)) {
      const char *prefix_name = lGetString(var_elem, VA_variable);
      next_var_elem = lNext(var_elem);

      if (!strncmp(prefix_name, prefix, prefix_len)) {
         lRemoveElem(*varl, &var_elem);
      } 
   }
   DEXIT;
   return;
}
Beispiel #19
0
/****** cull/dump_scan/lDumpList() ********************************************
*  NAME
*     lDumpList() -- Writes a list to a FILE stream
*
*  SYNOPSIS
*     int lDumpList(FILE *fp, const lList *lp, int indent) 
*
*  FUNCTION
*     Writes a list to a FILE stream. 
*
*  INPUTS
*     FILE *fp        - file stream 
*     const lList *lp - list 
*     int indent      - 
*
*  RESULT
*     int - error state
*         0 - OK
*        -1 - Error
*
*  NOTES
*     MT-NOTE: lDumpList() is not MT safe
*******************************************************************************/
int lDumpList(FILE *fp, const lList *lp, int indent) 
{
   lListElem *ep;
   int i, ret = ~EOF;

   char space[256];

   DENTER(CULL_LAYER, "lDumpList");

   space[0] = '\0';
   for (i = 0; i < indent; i++)
      strcat(space, INDENT_STRING);

   if (!fp) {
      LERROR(LEFILENULL);
      DEXIT;
      return -1;
   }
   if (!lp) {
      LERROR(LELISTNULL);
      DEXIT;
      return -1;
   }

   ret = fprintf(fp, "%s{ /* LIST BEGIN */\n", space);

   ret = fprintf(fp, "%s/* LISTNAME               */ \"%s\"\n", space, 
                 lGetListName(lp));
   ret = fprintf(fp, "%s/* NUMBER OF ELEMENTS     */ %d\n", space, 
                 lGetNumberOfElem(lp));

   ret = lDumpDescr(fp, lGetListDescr(lp), indent);

   for (ep = lFirst(lp); ep && ret != EOF; ep = lNext(ep))
      ret = lDumpElemFp(fp, ep, indent);

   ret = fprintf(fp, "%s} /* LIST END */\n", space);

   DEXIT;
   return (ret == EOF) ? -1 : 0;

}
Beispiel #20
0
lListElem *
host_list_locate(const lList *host_list, const char *hostname) 
{
   lListElem *ret = NULL;
   
   DENTER(TOP_LAYER, "host_list_locate");
   if (host_list != NULL) {
      if (hostname != NULL) {
         const lListElem *element = lFirst(host_list);

         if (element != NULL) {
            int nm = NoName;

            if (object_has_type(element, EH_Type)) {
               nm = object_get_primary_key(EH_Type);
            } else if (object_has_type(element, AH_Type)) {
               nm = object_get_primary_key(AH_Type);
            } else if (object_has_type(element, SH_Type)) {
               nm = object_get_primary_key(SH_Type);
            }
            ret = lGetElemHost(host_list, nm, hostname);
         }
      } else {
         CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC));
      }
   } else {
      /*
       * This is a normal case and no error
       * if e.g. someone tries to find a element at qmaster startup to 
       * check if a certain element should be added
       */
      ret = NULL;
   }
   
   DRETURN(ret);
}
Beispiel #21
0
static sge_callback_result
print_jatask_event(sge_evc_class_t *evc, object_description *object_base, sge_object_type type, 
                   sge_event_action action, lListElem *event, void *clientdata)
{
   char buffer[1024];
   dstring buffer_wrapper;

   DENTER(TOP_LAYER, "print_jatask_event");

   sge_dstring_init(&buffer_wrapper, buffer, sizeof(buffer));
   
   DPRINTF(("%s\n", event_text(event, &buffer_wrapper)));
   if (lGetPosViaElem(event, ET_type, SGE_NO_ABORT) >= 0) {
      u_long32 type = lGetUlong(event, ET_type);
      u_long32 timestamp = lGetUlong(event, ET_timestamp);
      
      if (type == sgeE_JATASK_MOD) { 
         lList *jat = lGetList(event,ET_new_version);
         u_long job_id  = lGetUlong(event, ET_intkey);
         u_long task_id = lGetUlong(event, ET_intkey2);
         lListElem *ep = lFirst(jat);
         u_long job_status = lGetUlong(ep, JAT_status);
         int task_running = (job_status==JRUNNING || job_status==JTRANSFERING);

         if (task_running) {
            fprintf(stdout,"JOB_START (%ld.%ld:ECL_TIME="sge_U32CFormat")\n", job_id ,task_id,sge_u32c(timestamp));
            fflush(stdout);  
            Global_jobs_running++;
         }
      }
   
      if (type == sgeE_JOB_FINAL_USAGE) { 
         /* lList *jat = lGetList(event,ET_new_version); */
         u_long job_id = lGetUlong(event, ET_intkey);
         u_long task_id = lGetUlong(event, ET_intkey2);
         /* lWriteElemTo(event, stdout); */
         fprintf(stdout,"JOB_FINISH (%ld.%ld:ECL_TIME="sge_U32CFormat")\n", job_id, task_id,sge_u32c(timestamp));
         Global_jobs_running--;
         fflush(stdout);  
      }
      if (type == sgeE_JOB_ADD) { 
         lList *jat = lGetList(event,ET_new_version);
         u_long job_id  = lGetUlong(event, ET_intkey);
         u_long task_id = lGetUlong(event, ET_intkey2);
         lListElem *ep = lFirst(jat);
         const char* job_project = lGetString(ep, JB_project);
         if (job_project == NULL) {
            job_project = "NONE";
         }
         fprintf(stdout,"JOB_ADD (%ld.%ld:ECL_TIME="sge_U32CFormat":project=%s)\n", job_id, task_id, sge_u32c(timestamp),job_project);
         Global_jobs_registered++;
         fflush(stdout);  
      }
      if (type == sgeE_JOB_DEL) { 
         u_long job_id  = lGetUlong(event, ET_intkey);
         u_long task_id = lGetUlong(event, ET_intkey2);
         fprintf(stdout,"JOB_DEL (%ld.%ld:ECL_TIME="sge_U32CFormat")\n", job_id, task_id,sge_u32c(timestamp));
         Global_jobs_registered--;
         fflush(stdout);  
      }

   }
   /* create a callback error to test error handling */
   if(type == SGE_TYPE_GLOBAL_CONFIG) {
      DEXIT;
      return SGE_EMA_FAILURE;
   }
   
   DEXIT;
   return SGE_EMA_OK;
}
/* - -- -- -- -- -- -- -- -- -- -- -- -- -- -

   user_args - a cull list(UE_Type) of users
   acl_args - a cull list(US_Type) of acl

   returns 
      0 on success
      -1 on error

*/
int sge_client_add_user(
sge_gdi_ctx_class_t *ctx,
lList **alpp,
lList *user_args,
lList *acl_args 
) {
   lListElem *userarg, *aclarg;
   lList *acl=NULL, *answers=NULL;
   const char *acl_name, *user_name;
   lCondition *where;
   lEnumeration *what;
   u_long32 status;
   int already;

   DENTER(TOP_LAYER, "sge_client_add_user");

   what = lWhat("%T(ALL)", US_Type);

   for_each(aclarg,acl_args) {
      acl_name = lGetString(aclarg, US_name);
      where = lWhere("%T(%I==%s)", US_Type, US_name, acl_name);

      for_each(userarg, user_args) {

         already = 0;
         user_name=lGetString(userarg, UE_name);
   
         /* get old acl */
         answers = ctx->gdi(ctx, SGE_US_LIST, SGE_GDI_GET, &acl, where, what, false);
         lFreeList(&answers);

         if (acl && lGetNumberOfElem(acl) > 0) {
            if (!lGetSubStr(lFirst(acl), UE_name, user_name, US_entries)) {
               lAddSubStr(lFirst(acl), UE_name, user_name, US_entries, UE_Type);

               /* mod the acl */
               answers = ctx->gdi(ctx, SGE_US_LIST, SGE_GDI_MOD, &acl, 
                        NULL, NULL, false);   
            } else {
               already = 1;
            }
         } else {
            /* build new list */
            lAddElemStr(&acl, US_name, acl_name, US_Type);
            lAddSubStr(lFirst(acl), UE_name, user_name, US_entries, UE_Type);
            
            /* add the acl */
            answers = ctx->gdi(ctx, SGE_US_LIST, SGE_GDI_ADD, &acl, 
                     NULL, NULL, false);   
         }

         if (already) {
            status = STATUS_EEXIST;
            SGE_ADD_MSG_ID( sprintf(SGE_EVENT, MSG_GDI_USERINACL_SS, user_name, acl_name));
         }
         else {
            if ((status = lGetUlong(lFirst(answers), AN_status))!=STATUS_OK) {
               const char *cp;
            
               cp = lGetString(lFirst(answers), AN_text);
               if (cp) {
                  sprintf(SGE_EVENT, "%s", cp);
               }
               else {
                  SGE_ADD_MSG_ID( sprintf(SGE_EVENT, MSG_GDI_CANTADDTOACL_SS, user_name, acl_name));
               }
            } else {
               sprintf(SGE_EVENT, MSG_GDI_ADDTOACL_SS, user_name, acl_name);
            }
            lFreeList(&answers);
         }
         answer_list_add(alpp, SGE_EVENT, status, 
            ((status == STATUS_OK) ? ANSWER_QUALITY_INFO : ANSWER_QUALITY_ERROR));
         lFreeList(&acl);

      }
/************************************************************
  sge_mod_sharetree - Master code

  Modify a share tree
  lListElem *ep,   This is the new share tree 
  lList **lpp,     list to change 
 ************************************************************/
int sge_mod_sharetree(sge_gdi_ctx_class_t *ctx,
                      lListElem *ep, lList **lpp, lList **alpp, 
                      char *ruser, char *rhost ) 
{
   int ret;
   int prev_version;
   int adding; 
   lList *found = NULL;
   object_description *object_base = object_type_get_object_description();

   DENTER(TOP_LAYER, "sge_mod_sharetree");

   /* do some checks */
   if (!ep || !ruser || !rhost) {
      CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC));
      answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EUNKNOWN;
   }

   ret = check_sharetree(alpp, ep, *object_base[SGE_TYPE_USER].list, 
                         *object_base[SGE_TYPE_PROJECT].list, 
                         NULL, &found);
   lFreeList(&found);
   if (ret) {
      /* alpp gets filled by check_sharetree() */
      DRETURN(STATUS_EUNKNOWN);
   }

   /* check for presence of sharetree list and create if neccesary */
   if (!*lpp) {
      prev_version = 0;
      *lpp = lCreateList("sharetree list", STN_Type);
      adding = 1;
   } else if (lGetNumberOfElem(*lpp) == 0) {
      prev_version = 0;
      adding = 1;
   } else {
      lListElem *first = lFirst(*lpp);
      /* real action: change user or project
         We simply replace the old element with the new one. If there is no
         old we simle add the new. */
     
      prev_version = lGetUlong(lFirst(*lpp), STN_version); 
      lRemoveElem(*lpp, &first);
      adding = 0;
   }

   lSetUlong(ep, STN_version, prev_version+1);

   id_sharetree(alpp, ep, 0, NULL);

   /* now insert new element */
   lAppendElem(*lpp, lCopyElem(ep));
  
   /* write sharetree to file */
   if (!sge_event_spool(ctx,
                        alpp, 0, sgeE_NEW_SHARETREE,
                        0, 0, NULL, NULL, NULL,
                        ep, NULL, NULL, true, true)) {

      /* answer list gets filled in sge_event_spool() */
      DEXIT;
      return ret;
   }

   if (adding) {
      INFO((SGE_EVENT, MSG_STREE_ADDSTREE_SSII, 
         ruser, rhost, lGetNumberOfNodes(ep, NULL, STN_children), lGetNumberOfLeafs(ep, NULL, STN_children)));
   } else {
      INFO((SGE_EVENT, MSG_STREE_MODSTREE_SSII, 
         ruser, rhost, lGetNumberOfNodes(ep, NULL, STN_children), lGetNumberOfLeafs(ep, NULL, STN_children)));
   }

   answer_list_add(alpp, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO);

   DEXIT;
   return STATUS_OK;
}
Beispiel #24
0
bool sge_parse_qrsub(sge_gdi_ctx_class_t *ctx, lList *pcmdline, lList **alpp, lListElem **ar)
{
   lListElem *ep = NULL, *next_ep = NULL;
   lList *lp = NULL;
   DENTER(TOP_LAYER, "sge_parse_qrsub");

   /*  -help 	 print this help */
   if ((ep = lGetElemStr(pcmdline, SPA_switch, "-help"))) {
      lRemoveElem(pcmdline, &ep);
      sge_usage(QRSUB, stdout);
      DEXIT;
      SGE_EXIT((void **)&ctx, 0);
   }

   /*  -a date_time 	 start time in [[CC]YY]MMDDhhmm[.SS] SGE_ULONG */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-a"))) {
      lSetUlong(*ar, AR_start_time, lGetUlong(ep, SPA_argval_lUlongT));
      lRemoveElem(pcmdline, &ep);
   }

   /*  -e date_time 	 end time in [[CC]YY]MMDDhhmm[.SS] SGE_ULONG*/
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-e"))) {
      lSetUlong(*ar, AR_end_time, lGetUlong(ep, SPA_argval_lUlongT));
      lRemoveElem(pcmdline, &ep);
   }

   /*  -d time 	 duration in TIME format SGE_ULONG */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-d"))) {
      lSetUlong(*ar, AR_duration, lGetUlong(ep, SPA_argval_lUlongT));
      lRemoveElem(pcmdline, &ep);
   }
   
   /*  -w e/v 	 validate availability of AR request, default e SGE_ULONG */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-w"))) {
      lSetUlong(*ar, AR_verify, lGetInt(ep, SPA_argval_lIntT));
      lRemoveElem(pcmdline, &ep);
   }
  
   /*  -N name 	 AR name SGE_STRING */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-N"))) {
      lSetString(*ar, AR_name, lGetString(ep, SPA_argval_lStringT));
      lRemoveElem(pcmdline, &ep);
   }
      
   /*  -A account_string 	 AR name in accounting record SGE_STRING */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-A"))) {
      lSetString(*ar, AR_account, lGetString(ep, SPA_argval_lStringT));
      lRemoveElem(pcmdline, &ep);
   }
     
   /*  -l resource_list 	 request the given resources  SGE_LIST */
   parse_list_simple(pcmdline, "-l", *ar, AR_resource_list, 0, 0, FLG_LIST_APPEND);
   centry_list_remove_duplicates(lGetList(*ar, AR_resource_list));

   /*  -u wc_user 	       access list SGE_LIST */
   /*  -u ! wc_user TBD: Think about eval_expression support in compare allowed and excluded lists */
   parse_list_simple(pcmdline, "-u", *ar, AR_acl_list, ARA_name, 0, FLG_LIST_MERGE);
   /*  -u ! list separation */
   lp = lGetList(*ar,  AR_acl_list);
   next_ep = lFirst(lp);
   while ((ep = next_ep)) {
      bool is_xacl = false;
      const char *name = lGetString(ep, ARA_name);

      next_ep = lNext(ep);
      if (name[0] == '!') { /* move this element to xacl_list */
         is_xacl = true;
         name++;
      }

      if (!is_hgroup_name(name)) {
         struct passwd *pw;
         struct passwd pw_struct;
         char *buffer;
         int size;
         stringT group;

         size = get_pw_buffer_size();
         buffer = sge_malloc(size);
         pw = sge_getpwnam_r(name, &pw_struct, buffer, size);
         
         if (pw == NULL) {
           answer_list_add_sprintf(alpp, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR, MSG_USER_XISNOKNOWNUSER_S, name);
           FREE(buffer);
           DRETURN(false);
         }
         sge_gid2group(pw->pw_gid, group, MAX_STRING_SIZE, MAX_NIS_RETRIES);
         lSetString(ep, ARA_group, group);
         FREE(buffer);
      }

      if (is_xacl) {
         lListElem *new_ep = lAddSubStr(*ar, ARA_name, name, AR_xacl_list, ARA_Type);
         lSetString(new_ep, ARA_group, lGetString(ep, ARA_group));
         lRemoveElem(lp, &ep);
      }

   }

   /*  -q wc_queue_list 	 reserve in queue(s) SGE_LIST */
   parse_list_simple(pcmdline, "-q", *ar, AR_queue_list, 0, 0, FLG_LIST_APPEND);

  /*    -pe pe_name slot_range reserve slot range for parallel jobs */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-pe"))) {
      lSetString(*ar, AR_pe, lGetString(ep, SPA_argval_lStringT)); /* SGE_STRING, */
      lSwapList(*ar, AR_pe_range, ep, SPA_argval_lListT);       /* SGE_LIST */
      lRemoveElem(pcmdline, &ep);
   }
   /*   AR_master_queue_list  -masterq wc_queue_list, SGE_LIST bind master task to queue(s) */
   parse_list_simple(pcmdline, "-masterq", *ar, AR_master_queue_list, 0, 0, FLG_LIST_APPEND);

   /*  -ckpt ckpt-name 	 reserve in queue with ckpt method SGE_STRING */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-ckpt"))) {
      lSetString(*ar, AR_checkpoint_name, lGetString(ep, SPA_argval_lStringT));
      lRemoveElem(pcmdline, &ep);
   }
   
   /*  -m b/e/a/n 	 define mail notification events SGE_ULONG */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-m"))) {
      u_long32 ul;
      u_long32 old_mail_opts;

      ul = lGetInt(ep, SPA_argval_lIntT);
      if  ((ul & NO_MAIL)) {
         lSetUlong(*ar, AR_mail_options, 0);
      } else {
         old_mail_opts = lGetUlong(*ar, AR_mail_options);
         lSetUlong(*ar, AR_mail_options, ul | old_mail_opts);
      }
      lRemoveElem(pcmdline, &ep);
   }

   /*   -M user[@host],... 	 notify these e-mail addresses SGE_LIST*/
   parse_list_simple(pcmdline, "-M", *ar, AR_mail_list, MR_host, MR_user, FLG_LIST_MERGE);

   /*  -he yes/no 	 hard error handling SGE_ULONG */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-he"))) {
      lSetUlong(*ar, AR_error_handling, lGetUlong(ep, SPA_argval_lUlongT));
      lRemoveElem(pcmdline, &ep);
   }

   /*   -now 	 reserve in queues with qtype interactive  SGE_ULONG */
   while ((ep = lGetElemStr(pcmdline, SPA_switch, "-now"))) {
      u_long32 ar_now = lGetUlong(*ar, AR_type);
      if(lGetInt(ep, SPA_argval_lIntT)) {
         JOB_TYPE_SET_IMMEDIATE(ar_now);
      } else {
         JOB_TYPE_CLEAR_IMMEDIATE(ar_now);
      }

      lSetUlong(*ar, AR_type, ar_now);

      lRemoveElem(pcmdline, &ep);
   }

  /* Remove the script elements. They are not stored in the ar structure */
  if ((ep = lGetElemStr(pcmdline, SPA_switch, STR_PSEUDO_SCRIPT))) {
      lRemoveElem(pcmdline, &ep);
   }

   if ((ep = lGetElemStr(pcmdline, SPA_switch, STR_PSEUDO_SCRIPTLEN))) {
      lRemoveElem(pcmdline, &ep);
   }

   if ((ep = lGetElemStr(pcmdline, SPA_switch, STR_PSEUDO_SCRIPTPTR))) {
      lRemoveElem(pcmdline, &ep);
   }

   ep = lFirst(pcmdline);   
   if(ep) {
      const char *option = lGetString(ep,SPA_switch);
      /* as jobarg are stored no switch values, need to be filtered */ 
      if(sge_strnullcmp(option, "jobarg") != 0) {
         answer_list_add_sprintf(alpp, STATUS_ESEMANTIC, ANSWER_QUALITY_ERROR,
                              MSG_PARSE_INVALIDOPTIONARGUMENTX_S,
                              lGetString(ep,SPA_switch)); 
      } else {
         answer_list_add_sprintf(alpp, STATUS_ESEMANTIC, ANSWER_QUALITY_ERROR,
                              MSG_PARSE_INVALIDOPTIONARGUMENT);
       }
      DRETURN(false);
   }

   if (lGetUlong(*ar, AR_start_time) == 0 && lGetUlong(*ar, AR_end_time) != 0 && lGetUlong(*ar, AR_duration) != 0) {
      lSetUlong(*ar, AR_start_time, lGetUlong(*ar, AR_end_time) - lGetUlong(*ar, AR_duration));
   } else if (lGetUlong(*ar, AR_start_time) != 0 && lGetUlong(*ar, AR_end_time) == 0 && lGetUlong(*ar, AR_duration) != 0) {
      lSetUlong(*ar, AR_end_time, duration_add_offset(lGetUlong(*ar, AR_start_time), lGetUlong(*ar, AR_duration)));
      lSetUlong(*ar, AR_duration, lGetUlong(*ar, AR_end_time) - lGetUlong(*ar, AR_start_time));
   } else if (lGetUlong(*ar, AR_start_time) != 0 && lGetUlong(*ar, AR_end_time) != 0 && lGetUlong(*ar, AR_duration) == 0) {
      lSetUlong(*ar, AR_duration, lGetUlong(*ar, AR_end_time) - lGetUlong(*ar, AR_start_time));
   }

   DRETURN(true);
}
/****** sge_c_report() *******************************************************
*  NAME
*     sge_c_report() -- process execd load report
*
*  SYNOPSIS
*     void sge_c_report(char *rhost, char *commproc, int id, lList *report_list)
*
*  FUNCTION
*
*  INPUTS
*     char *rhost
*     char *commproc
*     int id
*     lList *report_list
*
*  RESULT
*     void - nothing
*
*  NOTES
*     MT-NOTE: sge_c_report() is MT safe
*
******************************************************************************/
void sge_c_report(sge_gdi_ctx_class_t *ctx, char *rhost, char *commproc, int id, lList *report_list, monitoring_t *monitor)
{
   lListElem *hep = NULL;
   u_long32 rep_type;
   lListElem *report;
   int ret = 0;
   u_long32 this_seqno, last_seqno;
   u_long32 rversion;
   sge_pack_buffer pb;   
   bool is_pb_used = false;
   bool send_tag_new_conf = false;

   DENTER(TOP_LAYER, "sge_c_report");

   if (lGetNumberOfElem(report_list) == 0) {
      DPRINTF(("received empty report\n"));
      if (rhost != NULL) {
         WARNING((SGE_EVENT, MSG_QMASTER_RECEIVED_EMPTY_LOAD_REPORT_S, rhost));
      } else {
         WARNING((SGE_EVENT, MSG_QMASTER_RECEIVED_EMPTY_LOAD_REPORT_S, "unknown"));
      }
      DRETURN_VOID;
   }

   /* accept reports only from execd's */
   if (strcmp(prognames[EXECD], commproc)) {
      ERROR((SGE_EVENT, MSG_GOTSTATUSREPORTOFUNKNOWNCOMMPROC_S, commproc));
      DRETURN_VOID;
   }

   /* do not process load reports from old execution daemons */
   rversion = lGetUlong(lFirst(report_list), REP_version);
   if (verify_request_version(NULL, rversion, rhost, commproc, id)) {
      DRETURN_VOID;
   }
   
   this_seqno = lGetUlong(lFirst(report_list), REP_seqno);

   /* need exec host for all types of reports */
   if (!(hep = host_list_locate(*object_type_get_master_list(SGE_TYPE_EXECHOST), rhost))) {
      ERROR((SGE_EVENT, MSG_GOTSTATUSREPORTOFUNKNOWNEXECHOST_S, rhost));
      DRETURN_VOID;
   }

   /* prevent old reports being proceeded 
      frequent loggings of outdated reports can be an indication 
      of too high message traffic arriving at qmaster */ 
   last_seqno = lGetUlong(hep, EH_report_seqno);

   if ((this_seqno < last_seqno && (last_seqno - this_seqno) <= 9000) &&
      !(last_seqno > 9990 && this_seqno < 10)) {
      /* this must be an old report, log and then ignore it */
      INFO((SGE_EVENT, MSG_QMASTER_RECEIVED_OLD_LOAD_REPORT_UUS, 
               sge_u32c(this_seqno), sge_u32c(last_seqno), rhost));
      DRETURN_VOID;
   }
   
   lSetUlong(hep, EH_report_seqno, this_seqno);

   /* RU: */
   /* tag all reschedule_unknown list entries we hope to 
      hear about in that job report */
   update_reschedule_unknown_list(ctx, hep);

   /*
   ** process the reports one after the other
   ** usually there will be a load report
   ** and a configuration version report
   */
   for_each(report, report_list) {
      rep_type = lGetUlong(report, REP_type);

      switch (rep_type) {
      case NUM_REP_REPORT_LOAD:
      case NUM_REP_FULL_REPORT_LOAD:
         MONITOR_ELOAD(monitor); 
         /* Now handle execds load reports */
         if (lGetUlong(hep, EH_lt_heard_from) == 0 && rep_type != NUM_REP_FULL_REPORT_LOAD) {
            host_notify_about_full_load_report(ctx, hep);
         } else {
            if (!is_pb_used) {
               is_pb_used = true;
               init_packbuffer(&pb, 1024, 0);
            }
            sge_update_load_values(ctx, rhost, lGetList(report, REP_list));

            if (mconf_get_simulate_execds()) {
               lList *master_exechost_list = *object_type_get_master_list(SGE_TYPE_EXECHOST);
               lListElem *shep;
               lListElem *simhostElem=NULL; 

               for_each(shep, master_exechost_list) {
                  simhostElem = lGetSubStr(shep, CE_name, "load_report_host", EH_consumable_config_list);
                  if (simhostElem != NULL) {
                     const char *real_host = lGetString(simhostElem, CE_stringval);
                     if (real_host != NULL && sge_hostcmp(real_host, rhost) == 0) {
                        const char* sim_host = lGetHost(shep, EH_name);
                        lListElem *clp = NULL;

                        DPRINTF(("Copy load values of %s to simulated host %s\n",
                                rhost, sim_host));

                        for_each(clp, lGetList(report, REP_list)) {
                           if (strcmp(lGetHost(clp, LR_host), SGE_GLOBAL_NAME) != 0) {
                              lSetHost(clp, LR_host, sim_host);
                           }
                        }
                        sge_update_load_values(ctx, sim_host, lGetList(report, REP_list));
                     }
                  }
               }
            }

            pack_ack(&pb, ACK_LOAD_REPORT, this_seqno, 0, NULL);
         }
         break;
      case NUM_REP_REPORT_CONF: 
         MONITOR_ECONF(monitor); 
         if (sge_compare_configuration(hep, lGetList(report, REP_list)) != 0) {
            DPRINTF(("%s: configuration on host %s is not up to date\n", SGE_FUNC, rhost));
            send_tag_new_conf = true;
         }
         break;
         
      case NUM_REP_REPORT_PROCESSORS:
         /*
         ** save number of processors
         */
         MONITOR_EPROC(monitor);
         ret = update_license_data(ctx, hep, lGetList(report, REP_list)); 
         if (ret) {
            ERROR((SGE_EVENT, MSG_LICENCE_ERRORXUPDATINGLICENSEDATA_I, ret));
         }
         break;

      case NUM_REP_REPORT_JOB:
         MONITOR_EJOB(monitor);
         if (!is_pb_used) {
            is_pb_used = true;
            init_packbuffer(&pb, 1024, 0);
         }
         process_job_report(ctx, report, hep, rhost, commproc, &pb, monitor);
         break;

      default:   
         DPRINTF(("received invalid report type %ld\n", (long) rep_type));
      }
Beispiel #26
0
/*-------------------------------------------------------------------------*/
void qmonSetNxN(Widget w, lList *lp, int num_fields, ...)
{
   lListElem *ep;
   int i, row;
   int max_rows;
   int val;
   double dval;
   char buf[128];
   int *field;
   const char **col;
   va_list ap;
   
   DENTER(GUI_LAYER, "qmonSetNxN");
   
   /* clear the area */
   XtVaSetValues(w, XmNcells, NULL, NULL);
   
   if (!lp)
   {
      DEXIT;
      return;
   }

   field = malloc(num_fields*sizeof(int));
   col   = malloc(num_fields*sizeof(char *));
   if (field == NULL || col == NULL)
      abort();

   va_start(ap, num_fields);
   for(i=0; i<num_fields; i++)
      field[i] = va_arg(ap, int);

   XtVaGetValues(w, XmNrows, &max_rows, NULL);

   for (ep = lFirst(lp), row = 0; ep; ep = lNext(ep), row++)
   {
      if (row == max_rows)
      {
         XbaeMatrixAddRows(w, 
                           max_rows, 
                           NULL,       /* empty rows  */
                           NULL,       /* no lables   */
                           NULL,       /* no different colors */
                           1);         /* we add 1 rows      */
         max_rows++;
      }

      memset(col, 0, num_fields*sizeof(char *));

      /*
       * get column values
       */

      for(i=0; i<num_fields; i++)
      {
         switch (lGetType(lGetListDescr(lp), field[i]))
         {
            case lStringT:
               col[i] = (StringConst)lGetString(ep, field[i]);
               break;
            case lHostT:
               col[i] = (StringConst)lGetHost(ep,field[i]);
               break;
            case lUlongT:
               val = (int)lGetUlong(ep, field[i]);
#if 0
               if (val) {
                  sprintf(buf, "%d", val);
                  col[i] = buf;
               }
               else
                  col[i] = NULL;
#else
               sprintf(buf, "%d", val);
               col[i] = buf;
#endif
               break;
            case lDoubleT:
               dval = lGetDouble(ep, field[i]);
               sprintf(buf, "%.2f", dval);
               col[i] = buf;
               break;
         }
      }

      if (col[0])
      {
         /* FIX_CONST_GUI */
         for(i=0; i<num_fields; i++)
            XbaeMatrixSetCell(w, row, i, col[i] ? (String)col[i] : "");
      }
   }

   va_end(ap);
   free(field);
   free(col);
       
   DEXIT;
}
Beispiel #27
0
/*-------------------------------------------------------------------------*/
void qmonSet2xN(
Widget w,
lList *lp,
int field1,
int field2 
) {
   lListElem *ep;
   int row;
   int max_rows;
   const char *col1 = NULL, *col2 = NULL;
   int val;
   double dval;
   char buf[128];
   
   DENTER(GUI_LAYER, "qmonSet2xN");
   
   /* clear the area */
   XtVaSetValues(w, XmNcells, NULL, NULL);
   
   if (!lp) {
      DEXIT;
      return;
   }
      
   XtVaGetValues(w, XmNrows, &max_rows, NULL);

   for (ep = lFirst(lp), row = 0; ep; ep = lNext(ep), row++) {
      if (row == max_rows) {
         XbaeMatrixAddRows(w, 
                           max_rows, 
                           NULL,       /* empty rows  */
                           NULL,       /* no lables   */
                           NULL,       /* no different colors */
                           1);         /* we add 1 rows      */
         max_rows++;
      }
      /*
      ** the first column of the matrix can be string or host type
      **
      */
      switch (lGetType(lGetListDescr(lp), field1)) {
         case lStringT:
            col1 = (StringConst)lGetString(ep, field1);
            break;
         case lHostT:
            col1 = (StringConst)lGetHost(ep,field1);
            break;
      }
      /*
      ** the second column can be of different type
      */
      switch (lGetType(lGetListDescr(lp), field2)) {
         case lStringT:
            col2 = (StringConst)lGetString(ep, field2);
            break;
         case lHostT:
            col2 = (StringConst)lGetHost(ep,field2);
            break;
         case lUlongT:
            val = (int)lGetUlong(ep, field2);
            if (val) {
               sprintf(buf, "%d", val);
               col2 = buf;
            }
            else
               col2 = NULL;
            break;
         case lDoubleT:
            dval = lGetDouble(ep, field2);
            sprintf(buf, "%.2f", dval);
            col2 = buf;
            break;
      }

      if (col1) {
         /* FIX_CONST_GUI */
         XbaeMatrixSetCell(w, row, 0 , col1 ? (String)col1 : "");
         /* FIX_CONST_GUI */
         XbaeMatrixSetCell(w, row, 1 , col2 ? (String)col2 : "");
      }
   }
       
   DEXIT;
}
/****** qmaster/ckpt/sge_del_ckpt() *******************************************
*
*  NAME
*     sge_del_ckpt -- delete ckpt object in Master_Ckpt_List 
*
*  SYNOPSIS
*     int sge_del_ckpt(lListElem *ep, lList **alpp, char *ruser, char *rhost);
* 
*  FUNCTION
*     This function will be called from the framework which will
*     add/modify/delete generic gdi objects.
*     The purpose of this function is it to delete ckpt objects. 
*
*
*  INPUTS
*     ep          - element which should be deleted
*     alpp        - reference to an answer list.
*     ruser       - username of person who invoked this gdi request
*     rhost       - hostname of the host where someone initiated an gdi call
*
*  RESULT
*     [alpp] - error messages will be added to this list
*     0 - success
*     STATUS_EUNKNOWN - an error occured
******************************************************************************/ 
int sge_del_ckpt(sge_gdi_ctx_class_t *ctx, lListElem *ep, lList **alpp, char *ruser, char *rhost) 
{
   lListElem *found;
   int pos;
   const char *ckpt_name;
   lList **lpp = object_type_get_master_list(SGE_TYPE_CKPT);

   DENTER(TOP_LAYER, "sge_del_ckpt");

   if ( !ep || !ruser || !rhost ) {
      CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC));
      answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EUNKNOWN;
   }

   /* ep is no ckpt element, if ep has no CK_name */
   if ((pos = lGetPosViaElem(ep, CK_name, SGE_NO_ABORT)) < 0) {
      CRITICAL((SGE_EVENT, MSG_SGETEXT_MISSINGCULLFIELD_SS,
            lNm2Str(CK_name), SGE_FUNC));
      answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EUNKNOWN;
   }

   ckpt_name = lGetPosString(ep, pos);
   if (!ckpt_name) {
      CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC));
      answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EUNKNOWN;
   }                    
   found = ckpt_list_locate(*lpp, ckpt_name);

   if (!found) {
      ERROR((SGE_EVENT, MSG_SGETEXT_DOESNOTEXIST_SS, MSG_OBJ_CKPT, ckpt_name));
      answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EEXIST;
   }

   /* 
    * Try to find references in other objects
    */
   {
      lList *local_answer_list = NULL;

      if (ckpt_is_referenced(found, &local_answer_list, *(object_type_get_master_list(SGE_TYPE_JOB)),
                             *(object_type_get_master_list(SGE_TYPE_CQUEUE)))) {
         lListElem *answer = lFirst(local_answer_list);

         ERROR((SGE_EVENT, "denied: %s", lGetString(answer, AN_text)));
         answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN,
                         ANSWER_QUALITY_ERROR);
         lFreeList(&local_answer_list);
         DEXIT;
         return STATUS_EUNKNOWN;
      }
   }

   /* remove ckpt file 1st */
   if (!sge_event_spool(ctx, alpp, 0, sgeE_CKPT_DEL, 0, 0, ckpt_name, NULL, NULL,
                        NULL, NULL, NULL, true, true)) {
      ERROR((SGE_EVENT, MSG_CANTSPOOL_SS, MSG_OBJ_CKPT, ckpt_name));
      answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR);
      DEXIT;
      return STATUS_EDISK;
   }

   /* now we can remove the element */
   lRemoveElem(*lpp, &found);

   INFO((SGE_EVENT, MSG_SGETEXT_REMOVEDFROMLIST_SSSS,
            ruser, rhost, ckpt_name, MSG_OBJ_CKPT));
   answer_list_add(alpp, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO);
   DEXIT;
   return STATUS_OK;
}                     
Beispiel #29
0
/*-------------------------------------------------------------------------*/
static Boolean qmonSchedGet(lListElem *sep) {
   int job_info;
   lList *alp = NULL;
   String str;
   char buf[BUFSIZ];

   DENTER(GUI_LAYER, "qmonSchedGet");

   if (!sep) {
      goto error_exit;
   }

   /*
   ** get entries from dialog
   */
   XmtDialogGetDialogValues(qmon_sconf, &data);

/**
printf("<-data.algorithm: '%s'\n", data.algorithm ? data.algorithm : "-NA-");
printf("<-data.schedule_interval: '%s'\n", data.schedule_interval ? data.schedule_interval : "-NA-");
printf("<-data.sc_params: '%s'\n", data.sc_params ? data.sc_params : "-NA-");
printf("<-data.maxujobs: '%d'\n", data.maxujobs );
printf("<-data.flush_submit_secs: '%d'\n", data.flush_submit_secs );
printf("<-data.flush_finish_secs: '%d'\n", data.flush_finish_secs );
printf("<-data.max_reservation: '%d'\n", data.max_reservation );
printf("<-data.queue_sort_method: '%d'\n", data.queue_sort_method );
printf("<-data.load_adjustment_decay_time: '%s'\n", data.load_adjustment_decay_time ? data.load_adjustment_decay_time : "-NA-");
printf("<-data.load_formula: '%s'\n", data.load_formula ? data.load_formula : "-NA-");
**/

   if (!data.algorithm || data.algorithm[0] == '\0') {
      qmonMessageShow(qmon_sconf, True, "@{Algorithm required!}");
      goto error_exit;
   }
   lSetString(sep, SC_algorithm, data.algorithm);
  
   if (!data.schedule_interval || data.schedule_interval[0] == '\0') {
      qmonMessageShow(qmon_sconf, True, "@{Schedule Interval required!}");
      goto error_exit;
   }
   lSetString(sep, SC_schedule_interval, data.schedule_interval);
  
   lSetString(sep, SC_params, data.sc_params);

   lSetUlong(sep, SC_maxujobs, (u_long32) data.maxujobs);

   lSetUlong(sep, SC_flush_submit_sec, (u_long32) data.flush_submit_secs);
   lSetUlong(sep, SC_flush_finish_sec, (u_long32) data.flush_finish_secs);

   lSetUlong(sep, SC_max_reservation, (u_long32) data.max_reservation);
  
   lSetUlong(sep, SC_queue_sort_method, (u_long32) data.queue_sort_method);

   /*
   ** load adjustments need special treatment
   */
   lSetList(sep, SC_job_load_adjustments, data.job_load_adjustments);
   data.job_load_adjustments = NULL;

   if (!data.load_adjustment_decay_time || 
         data.load_adjustment_decay_time[0] == '\0') {
      qmonMessageShow(qmon_sconf, True, "@{Load Adjustment Decay Time required!}");
      goto error_exit;
   }
   lSetString(sep, SC_load_adjustment_decay_time, 
                  data.load_adjustment_decay_time);
  
   if (!data.load_formula || data.load_formula[0] == '\0') {
      qmonMessageShow(qmon_sconf, True, "@{Load Formula required!}");
      goto error_exit;
   }
   lSetString(sep, SC_load_formula, data.load_formula);
  
   if (!data.reprioritize_interval|| 
         data.reprioritize_interval[0] == '\0') {
      qmonMessageShow(qmon_sconf, True, "@{Reprioritize Interval required!}");
      goto error_exit;
   }
   lSetString(sep, SC_reprioritize_interval, data.reprioritize_interval);

   if (!data.default_duration|| 
         data.default_duration[0] == '\0') {
      qmonMessageShow(qmon_sconf, True, "@{Default duration required!}");
      goto error_exit;
   }
   lSetString(sep, SC_default_duration, data.default_duration);
   /*
   ** schedd_job_info needs some extras
   ** see comment for schedd_job_info in qmonScheddSet
   */
   job_info = XmtChooserGetState(sconf_job_info);
   switch (job_info) {
      case 0:
         lSetString(sep, SC_schedd_job_info, "false");
         break;
      case 1:
         lSetString(sep, SC_schedd_job_info, "true");
         break;
      case 2:
         str = XmtInputFieldGetString(sconf_job_range);
         {
            lList *range_list = NULL;

            range_list_parse_from_string(&range_list, &alp, str,
                                         1, 0, INF_NOT_ALLOWED);
            lFreeList(&range_list);
         }
         if (alp) {
            qmonMessageShow(sconf_job_range, True, (StringConst)lGetString(lFirst(alp), AN_text));
            lFreeList(&alp);
            goto error_exit;
         }
         if (str && str[0] != '\0') {
            strcpy(buf, "job_list ");
            strcat(buf, str);
            lSetString(sep, SC_schedd_job_info, buf);
         }
         else {
            qmonMessageShow(qmon_sconf, True, "@{Job Range required!}");
            goto error_exit;
         }
   }

/* printf("------> qmonSchedGet\n"); */
/* lWriteElemTo(sep, stdout);    */

   qmonSchedFreeData();
   DRETURN(True);
error_exit:
   qmonSchedFreeData();
   DRETURN(False);
}
lList *cull_unparse_job_parameter(
sge_gdi_ctx_class_t *ctx,
lList **pcmdline,
lListElem *job,
int flags 
) {
   const char *cp;
   u_long32 ul;
   lList *answer = NULL;
   char str[1024 + 1];
   lList *lp;
   int ret;
   lListElem *ep_opt;
   const char *username = ctx->get_username(ctx);
   const char *qualified_hostname = ctx->get_qualified_hostname(ctx);

   DENTER(TOP_LAYER, "cull_unparse_job_parameter");

   /*
   ** -a
   ** problem with submission time, but that is not a good
   ** default option anyway, is not unparsed
   */

   /*
   ** -A
   */
   if (sge_unparse_account_string(job, pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }

   /*
   ** -c
   */
   if (sge_unparse_checkpoint_option(job, pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }
  
   /*
    * -ckpt 
    */
   if (sge_unparse_string_option(job, JB_checkpoint_name, "-ckpt", 
            pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }


   /*
   ** -cwd
   */
   if (lGetString(job, JB_cwd)) {
      ep_opt = sge_add_noarg(pcmdline, cwd_OPT, "-cwd", NULL);
   }

   /*
    * -P
    */
   if (sge_unparse_string_option(job, JB_project, "-P",
            pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }

#if 0
   /*
   ** -C
   */
   if (sge_unparse_string_option(job, JB_directive_prefix, "-C", 
            pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }
#endif   

   /*
   ** -e
   */
   if (sge_unparse_path_list(job, JB_stderr_path_list, "-e", pcmdline, 
                     &answer) != 0) {
      DEXIT;
      return answer;
   }

   /*
   ** -h, here only user hold supported at the moment
   */
   if  ((ul = lGetUlong(lFirst(lGetList(job, JB_ja_tasks)), JAT_hold))) {
      ep_opt = sge_add_noarg(pcmdline, h_OPT, "-h", NULL);
   }

   /*
   ** -hold_jid
   */
   if ((lp = lGetList(job, JB_jid_request_list))) {
      int fields[] = { JRE_job_name, 0 };
      const char *delis[] = {NULL, ",", NULL};

      ret = uni_print_list(NULL, str, sizeof(str) - 1, lp, fields, delis, 0);
      if (ret) {
         DPRINTF(("Error %d formatting jid_request_list as -hold_jid\n", ret));
         sprintf(str, MSG_LIST_ERRORFORMATINGJIDPREDECESSORLISTASHOLDJID);
         answer_list_add(&answer, str, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
         return answer;
      }
      ep_opt = sge_add_arg(pcmdline, hold_jid_OPT, lListT, "-hold_jid", str);
      lSetList(ep_opt, SPA_argval_lListT, lCopyList("hold_jid list", lp));      
   }

   /*
   ** -hold_jid_ad
   */
   if ((lp = lGetList(job, JB_ja_ad_request_list))) {
      int fields[] = { JRE_job_name, 0 };
      const char *delis[] = {NULL, ",", NULL};

      ret = uni_print_list(NULL, str, sizeof(str) - 1, lp, fields, delis, 0);
      if (ret) {
         DPRINTF(("Error %d formatting ja_ad_request_list as -hold_jid_ad\n", ret));
         sprintf(str, MSG_LIST_ERRORFORMATINGJIDPREDECESSORLISTASHOLDJIDAD);
         answer_list_add(&answer, str, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
         return answer;
      }
      ep_opt = sge_add_arg(pcmdline, hold_jid_ad_OPT, lListT, "-hold_jid_ad", str);
      lSetList(ep_opt, SPA_argval_lListT, lCopyList("hold_jid_ad list", lp));      
   }

   /*
   ** -i
   */
   if (sge_unparse_path_list(job, JB_stdin_path_list, "-i", pcmdline, 
                     &answer) != 0) {
      DEXIT;
      return answer;
   }

   /*
   ** -j
   */
   if ((ul = lGetBool(job, JB_merge_stderr))) {
      ep_opt = sge_add_arg(pcmdline, j_OPT, lIntT, "-j", "y");
      lSetInt(ep_opt, SPA_argval_lIntT, true);
   }
   
   /*
   ** -jid
   */
   if ((lp = lGetList(job, JB_job_identifier_list))) {
      int fields[] = { JRE_job_number, 0};
      const char *delis[] = {"", ",", NULL};

      ret = uni_print_list(NULL, str, sizeof(str) - 1, lp, fields, delis, 
         0);
      if (ret) {
         DPRINTF(("Error %d formatting job_identifier_list as -jid\n", ret));
         sprintf(str, MSG_LIST_ERRORFORMATINGJOBIDENTIFIERLISTASJID);
         answer_list_add(&answer, str, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
         return answer;
      }
      ep_opt = sge_add_arg(pcmdline, jid_OPT, lListT, "-jid", str);
      lSetList(ep_opt, SPA_argval_lListT, lCopyList("jid list", lp));      
   }

   /*
   ** -js
   */
   if ((ul = lGetUlong(job, JB_jobshare)) != 0)  {
      sprintf(str, sge_u32, ul);
      ep_opt = sge_add_arg(pcmdline, js_OPT, lUlongT, "-js", str);
      lSetUlong(ep_opt, SPA_argval_lUlongT, ul);
   }

   /*
   ** -lj is in parsing but can't be unparsed here
   */

   /*
   ** -l
   */
   if (sge_unparse_resource_list(job, JB_hard_resource_list,
            pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }
   if (sge_unparse_resource_list(job, JB_soft_resource_list,
            pcmdline, &answer) != 0) {
      DEXIT;
      return answer;
   }






   /*
   ** -m
   */
   if ((ul = lGetUlong(job, JB_mail_options))) {
      cp = sge_unparse_mail_options(ul);
      if (!cp) {
         DPRINTF(("Error unparsing mail options\n"));
         sprintf(str, MSG_PARSE_ERRORUNPARSINGMAILOPTIONS);
         answer_list_add(&answer, str, STATUS_ESYNTAX, ANSWER_QUALITY_ERROR);
         return answer;
      }
      ep_opt = sge_add_arg(pcmdline, m_OPT, lIntT, "-m", cp);
      lSetInt(ep_opt, SPA_argval_lIntT, ul);
   }

   /*
   ** -M obviously a problem!!!
   ** not unparsed at the moment
   ** does it make sense as a default, after all?
   */
   if ((lp = lGetList(job, JB_mail_list))) {
      lList *lp_new = NULL;
      lListElem *ep_new = NULL;
      lListElem *ep = NULL;
      const char *host;
      const char *user;

      /*
      ** or rather take all if there are more than one elements?
      */
      for_each(ep, lp) {
         user = lGetString(ep, MR_user);
         host = lGetHost(ep, MR_host);
         if (sge_strnullcmp(user, username) || 
             sge_hostcmp(host, qualified_hostname)) {
            lp_new = lCreateList("mail list", MR_Type);
            ep_new = lAddElemStr(&lp_new, MR_user, user, MR_Type);
            lSetHost(ep_new, MR_host, host);
         }
      }