Beispiel #1
0
/****** sgeobj/var/var_list_add_as_set() ***************************************
*  NAME
*     var_list_add_as_set() -- Concatenate two lists as sets
*
*  SYNOPSIS
*     int var_list_add_as_set(lList *lp0, lList *lp1) 
*
*  FUNCTION
*     Concatenate two lists of equal type throwing away the second list.
*     Elements in the second list will replace elements with the same key in the
*     the first list.  If the first list contains duplicate element keys, only
*     the first element with a given key will be replaced by an element from the
*     second list with the same key.
*
*  INPUTS
*     lList *lp0 - first list 
*     lList *lp1 - second list 
*
*  RESULT
*     int - error state
*         0 - OK
*        -1 - Error
******************************************************************************/
int var_list_add_as_set(lList *lp0, lList *lp1) 
{
   lListElem *ep0, *ep1;
   const lDescr *dp0, *dp1;
   const char *name, *value;

   DENTER(CULL_LAYER, "var_list_add_as_set");

   if (lp1 == NULL || lp0 == NULL) {
      DRETURN(-1);
   }

   /* Check if the two lists are equal */
   dp0 = lGetListDescr(lp0);
   dp1 = lGetListDescr(lp1);
   if (lCompListDescr(dp0, dp1) != 0) {
      DRETURN(-1);
   }

   while (lp1->first != NULL) {
      /* Get the first element from the second list */
      if ((ep1 = lDechainElem(lp1, lp1->first)) == NULL) {
         DRETURN(-1);
      }
   
      /* Get it's name, and use the name to look for a matching element in the
       * first list. */
      name = lGetString(ep1, VA_variable);
      ep0 = lGetElemStr(lp0, VA_variable, name);

      /* If there is a matching element in the first list, set it's value to the
       * value of the element from the second list. */
      if (ep0 != NULL) {
         value = lGetString(ep1, VA_value);         
         lSetString(ep0, VA_value, value);
         lFreeElem(&ep1);
      }
      /* If there is no matching element, add the element from the second list
       * to the first list. */
      else {
         if (lAppendElem(lp0, ep1) == -1) {
            DRETURN(-1);
         }
      }
   }

   /* The second list is no longer needed. */
   lFreeList(&lp1);

   DRETURN(0);
}
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;
}
int schedd_log_list(lList **monitor_alpp, bool monitor_next_run, const char *logstr, lList *lp, int nm) {
   int fields[] = { 0, 0 };
   const char *delis[] = {NULL, " ", NULL};
   lList *lp_part = NULL;
   lListElem *ep = NULL;

   DENTER(TOP_LAYER, "schedd_log_list");

#ifndef WIN32NATIVE

   if (monitor_alpp == NULL && !monitor_next_run) {
      DRETURN(0);
   }

   fields[0] = nm;

   for_each(ep, lp) {
      if (!lp_part) {
         lp_part = lCreateList("partial list", lGetListDescr(lp));
      }
      lAppendElem(lp_part, lCopyElem(ep));
      if ((lGetNumberOfElem(lp_part) == NUM_ITEMS_ON_LINE) || !lNext(ep)) {
         char log_string[2048];

         sge_strlcpy(log_string, logstr, sizeof(log_string));
#ifndef WIN32NATIVE
         uni_print_list(NULL,
                        log_string + strlen(log_string),
                        sizeof(log_string) - strlen(log_string) - 1,
                        lp_part,
                        fields, delis, 0);
#endif
         schedd_log(log_string, monitor_alpp, monitor_next_run);
         lFreeList(&lp_part);
         lp_part = NULL;
      }
   }
#else
   DPRINTF(("schedd_log_list does nothing for QMonNT !!!\n"));
#endif

   DEXIT;
   return 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 #5
0
/****** Eventmirror/pe_task/pe_task_update_master_list() ***********************
*  NAME
*     pe_task_update_master_list() -- update parallel tasks of an array task
*
*  SYNOPSIS
*     bool 
*     pe_task_update_master_list(sge_object_type type, sge_event_action action, 
*                                lListElem *event, void *clientdata) 
*
*  FUNCTION
*     Update the list of parallel tasks of an array task
*     based on an event.
*     The function is called from the event mirroring interface.
*
*     The scaled usage list of a parallel task is not updated
*     by this function, as this data is maintained by a 
*     separate event.
*
*  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
*     Eventmirror/sge_mirror_update_master_list()
*******************************************************************************/
sge_callback_result
pe_task_update_master_list(sge_evc_class_t *evc, object_description *object_base, sge_object_type type, 
                           sge_event_action action, lListElem *event, void *clientdata)
{
   u_long32 job_id; 
   lListElem *job = NULL; 

   const char *pe_task_id = NULL;     
   lListElem *pe_task = NULL;

   u_long32 ja_task_id;
   lListElem *ja_task = NULL; 
   lList *pe_task_list = NULL;
   const lDescr *pe_task_descr = NULL;

   lList *usage = NULL;

   char id_buffer[MAX_STRING_SIZE];
   dstring id_dstring;

   DENTER(TOP_LAYER, "pe_task_update_master_list");

   sge_dstring_init(&id_dstring, id_buffer, MAX_STRING_SIZE);

   job_id = lGetUlong(event, ET_intkey);
   ja_task_id = lGetUlong(event, ET_intkey2);
   pe_task_id = lGetString(event, ET_strkey);
   
   job = job_list_locate(*sge_master_list(object_base, SGE_TYPE_JOB), job_id);
   if (job == NULL) {
      ERROR((SGE_EVENT, MSG_JOB_CANTFINDJOBFORUPDATEIN_SS, 
             job_get_id_string(job_id, 0, NULL, &id_dstring), SGE_FUNC));
      DEXIT;
      return SGE_EMA_FAILURE;
   }
   
   ja_task = job_search_task(job, NULL, ja_task_id);
   if (ja_task == NULL) {
      ERROR((SGE_EVENT, MSG_JOB_CANTFINDJATASKFORUPDATEIN_SS, 
             job_get_id_string(job_id, ja_task_id, NULL, &id_dstring), SGE_FUNC));
      DEXIT;
      return SGE_EMA_FAILURE;
   }
   
   pe_task = ja_task_search_pe_task(ja_task, pe_task_id);

   pe_task_list = lGetList(ja_task, JAT_task_list);
   pe_task_descr = lGetListDescr(lGetList(event, ET_new_version)); 
  
   if (action == SGE_EMA_MOD) {
      /* modify event for pe_task.
       * we may not update
       * - PET_scaled_usage - it is maintained by JOB_USAGE events
       */
      if (pe_task == NULL) {
         ERROR((SGE_EVENT, MSG_JOB_CANTFINDPETASKFORUPDATEIN_SS, 
                job_get_id_string(job_id, ja_task_id, pe_task_id, &id_dstring), SGE_FUNC));
         DEXIT;
         return SGE_EMA_FAILURE;
      }
      lXchgList(pe_task, PET_scaled_usage, &usage);
   }
 
   if (sge_mirror_update_master_list(&pe_task_list, pe_task_descr, pe_task, 
                                     job_get_id_string(job_id, ja_task_id, 
                                                       pe_task_id, &id_dstring),
                                     action, event) != SGE_EM_OK) {
      lFreeList(&usage);
      DEXIT;
      return SGE_EMA_FAILURE;
   }

   /* restore pe_task list after modify event */
   if (action == SGE_EMA_MOD) {
      pe_task = ja_task_search_pe_task(ja_task, pe_task_id);
      if (pe_task == NULL) {
         ERROR((SGE_EVENT, MSG_JOB_CANTFINDPETASKFORUPDATEIN_SS, 
                job_get_id_string(job_id, ja_task_id, pe_task_id, &id_dstring), SGE_FUNC));
         lFreeList(&usage);       
         DEXIT;
         return SGE_EMA_FAILURE;
      }

      lXchgList(pe_task, PET_scaled_usage, &usage);
      lFreeList(&usage);
   }

   /* first petask add event could have created new pe_task list for job */
   if (lGetList(ja_task, JAT_task_list) == NULL && pe_task_list != NULL) {
      lSetList(ja_task, JAT_task_list, pe_task_list);
   }

   DEXIT;
   return SGE_EMA_OK;
}
/****** qmaster/threads/sge_scheduler_main() **********************************
*  NAME
*     sge_scheduler_main() -- main function of the scheduler thread 
*
*  SYNOPSIS
*     void * sge_scheduler_main(void *arg) 
*
*  FUNCTION
*     Main function of the scheduler thread, 
*
*  INPUTS
*     void *arg - pointer to the thread function (type cl_thread_settings_t*) 
*
*  RESULT
*     void * - always NULL 
*
*  NOTES
*     MT-NOTE: sge_scheduler_main() is MT safe 
*
*     MT-NOTE: this is a thread function. Do NOT use this function
*     MT-NOTE: in any other way!
*
*  SEE ALSO
*     qmaster/threads/sge_scheduler_initialize() 
*     qmaster/threads/sge_scheduler_cleanup_thread() 
*     qmaster/threads/sge_scheduler_terminate() 
*     qmaster/threads/sge_scheduler_main() 
*******************************************************************************/
void *
sge_scheduler_main(void *arg)
{
   time_t next_prof_output = 0;
   monitoring_t monitor;
   sge_gdi_ctx_class_t *ctx = NULL;
   sge_evc_class_t *evc = NULL;
   lList *alp = NULL;
   sge_where_what_t where_what;
   cl_thread_settings_t *thread_config = (cl_thread_settings_t*)arg;
   bool do_shutdown = false;
   bool do_endlessly = true;
   bool local_ret = true;

   DENTER(TOP_LAYER, "sge_scheduler_main");

   memset(&where_what, 0, sizeof(where_what));

   /*
    * startup
    */
   if (local_ret) {
      /* initialize commlib thread */
      cl_thread_func_startup(thread_config);

      /* initialize monitoring */
      sge_monitor_init(&monitor, thread_config->thread_name, SCH_EXT, SCT_WARNING, SCT_ERROR);
      sge_qmaster_thread_init(&ctx, SCHEDD, SCHEDD_THREAD, true);

      /* register at profiling module */
      set_thread_name(pthread_self(), "Scheduler Thread");
      conf_update_thread_profiling("Scheduler Thread");
      DPRINTF((SFN" started\n", thread_config->thread_name));

      /* initialize schedd_runnlog logging */
      schedd_set_schedd_log_file(ctx);
   }

   /* set profiling parameters */
   prof_set_level_name(SGE_PROF_EVENTMASTER, NULL, NULL);
   prof_set_level_name(SGE_PROF_SPOOLING, NULL, NULL);
   prof_set_level_name(SGE_PROF_CUSTOM0, "scheduler", NULL);
   prof_set_level_name(SGE_PROF_CUSTOM1, "pending ticket calculation", NULL);
   prof_set_level_name(SGE_PROF_CUSTOM3, "job sorting", NULL);
   prof_set_level_name(SGE_PROF_CUSTOM4, "job dispatching", NULL);
   prof_set_level_name(SGE_PROF_CUSTOM5, "send orders", NULL);
   prof_set_level_name(SGE_PROF_CUSTOM6, "scheduler event loop", NULL);
   prof_set_level_name(SGE_PROF_CUSTOM7, "copy lists", NULL);
   prof_set_level_name(SGE_PROF_SCHEDLIB4, NULL, NULL);

   /* set-up needed for 'schedule' file */
   serf_init(schedd_serf_record_func, schedd_serf_newline);
   schedd_set_serf_log_file(ctx);

   /*
    * prepare event client/mirror mechanism
    */
   if (local_ret) {
      local_ret = sge_gdi2_evc_setup(&evc, ctx, EV_ID_SCHEDD, &alp, "scheduler");
      DPRINTF(("prepared event client/mirror mechanism\n"));
   }

   /*
    * register as event mirror
    */
   if (local_ret) {
      sge_mirror_initialize(evc, EV_ID_SCHEDD, "scheduler",
                            false, &event_update_func, &sge_mod_event_client,
                            &sge_add_event_client, &sge_remove_event_client,
                            &sge_handle_event_ack);
      evc->ec_register(evc, false, NULL, &monitor);
      evc->ec_set_busy_handling(evc, EV_BUSY_UNTIL_RELEASED);
      DPRINTF(("registered at event mirror\n"));
   }

   /*
    * subscribe necessary data
    */
   if (local_ret) {
      ensure_valid_what_and_where(&where_what);
      subscribe_scheduler(evc, &where_what);
      DPRINTF(("subscribed necessary data from event master\n"));
   }

   /* 
    * schedulers main loop
    */
   if (local_ret) {
      while (do_endlessly) {
         bool handled_events = false;
         lList *event_list = NULL;
         int execute = 0;
         double prof_copy = 0.0;
         double prof_total = 0.0;
         double prof_init = 0.0;
         double prof_free = 0.0;
         double prof_run = 0.0;
         lList *orders = NULL;

         if (sconf_get_profiling()) {
            prof_start(SGE_PROF_OTHER, NULL);
            prof_start(SGE_PROF_PACKING, NULL);
            prof_start(SGE_PROF_EVENTCLIENT, NULL);
            prof_start(SGE_PROF_MIRROR, NULL);
            prof_start(SGE_PROF_GDI, NULL);
            prof_start(SGE_PROF_HT_RESIZE, NULL);
            prof_start(SGE_PROF_CUSTOM0, NULL);
            prof_start(SGE_PROF_CUSTOM1, NULL);
            prof_start(SGE_PROF_CUSTOM3, NULL);
            prof_start(SGE_PROF_CUSTOM4, NULL);
            prof_start(SGE_PROF_CUSTOM5, NULL);
            prof_start(SGE_PROF_CUSTOM6, NULL);
            prof_start(SGE_PROF_CUSTOM7, NULL);
            prof_start(SGE_PROF_SCHEDLIB4, NULL);
         } else {
            prof_stop(SGE_PROF_OTHER, NULL);
            prof_stop(SGE_PROF_PACKING, NULL);
            prof_stop(SGE_PROF_EVENTCLIENT, NULL);
            prof_stop(SGE_PROF_MIRROR, NULL);
            prof_stop(SGE_PROF_GDI, NULL);
            prof_stop(SGE_PROF_HT_RESIZE, NULL);
            prof_stop(SGE_PROF_CUSTOM0, NULL);
            prof_stop(SGE_PROF_CUSTOM1, NULL);
            prof_stop(SGE_PROF_CUSTOM3, NULL);
            prof_stop(SGE_PROF_CUSTOM4, NULL);
            prof_stop(SGE_PROF_CUSTOM5, NULL);
            prof_stop(SGE_PROF_CUSTOM6, NULL);
            prof_stop(SGE_PROF_CUSTOM7, NULL);
            prof_stop(SGE_PROF_SCHEDLIB4, NULL);
         }

         /*
          * Wait for new events
          */
         MONITOR_IDLE_TIME(sge_scheduler_wait_for_event(evc, &event_list), (&monitor), mconf_get_monitor_time(), 
                           mconf_is_monitor_message());

         /* If we lost connection we have to register again */
         if (evc->ec_need_new_registration(evc)) {
            lFreeList(&event_list);
            if (evc->ec_register(evc, false, NULL, &monitor) == true) {
               DPRINTF(("re-registered at event master!\n"));
            }
         }

         if (event_list != NULL) {
            /* check for shutdown */
            do_shutdown = (lGetElemUlong(event_list, ET_type, sgeE_SHUTDOWN) != NULL) ? true : false;

            /* update mirror and free data */
            if (do_shutdown == false && sge_mirror_process_event_list(evc, event_list) == SGE_EM_OK) {
               handled_events = true;
               DPRINTF(("events handled\n"));
            } else {
               DPRINTF(("events contain shutdown event - ignoring events\n"));
            }
            lFreeList(&event_list);
         }
 
         /* if we actually got events, start the scheduling run and further event processing */
         if (handled_events == true) {
            lList *answer_list = NULL;
            scheduler_all_data_t copy;
            lList *master_cqueue_list = *(object_type_get_master_list(SGE_TYPE_CQUEUE));
            lList *master_job_list = *object_type_get_master_list(SGE_TYPE_JOB);
            lList *master_userset_list = *object_type_get_master_list(SGE_TYPE_USERSET);
            lList *master_project_list = *object_type_get_master_list(SGE_TYPE_PROJECT);
            lList *master_exechost_list= *object_type_get_master_list(SGE_TYPE_EXECHOST);
            lList *master_rqs_list= *object_type_get_master_list(SGE_TYPE_RQS);
            lList *master_centry_list = *object_type_get_master_list(SGE_TYPE_CENTRY);
            lList *master_ckpt_list = *object_type_get_master_list(SGE_TYPE_CKPT);
            lList *master_user_list = *object_type_get_master_list(SGE_TYPE_USER);
            lList *master_ar_list = *object_type_get_master_list(SGE_TYPE_AR);
            lList *master_pe_list = *object_type_get_master_list(SGE_TYPE_PE);
            lList *master_hgrp_list = *object_type_get_master_list(SGE_TYPE_HGROUP);
            lList *master_sharetree_list = *object_type_get_master_list(SGE_TYPE_SHARETREE);

            /* delay scheduling for test purposes, see issue GE-3306 */
            if (SGE_TEST_DELAY_SCHEDULING > 0) {
               sleep(SGE_TEST_DELAY_SCHEDULING);
            }

            PROF_START_MEASUREMENT(SGE_PROF_CUSTOM6);
            PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7);

            if (__CONDITION(INFOPRINT)) {
               dstring ds;
               char buffer[128];

               sge_dstring_init(&ds, buffer, sizeof(buffer));
               DPRINTF(("================[SCHEDULING-EPOCH %s]==================\n",
                        sge_at_time(0, &ds)));
               sge_dstring_free(&ds);
            }

            /*
             * If there were new events then
             * copy/filter data necessary for the scheduler run
             * and run the scheduler method
             */
            memset(&copy, 0, sizeof(copy));

            copy.dept_list = lSelect("", master_userset_list, where_what.where_dept, where_what.what_acldept);
            copy.acl_list = lSelect("", master_userset_list, where_what.where_acl, where_what.what_acldept);

            DPRINTF(("RAW CQ:%d, J:%d, H:%d, C:%d, A:%d, D:%d, P:%d, CKPT:%d,"
                     " US:%d, PR:%d, RQS:%d, AR:%d, S:nd:%d/lf:%d\n",
               lGetNumberOfElem(master_cqueue_list),
               lGetNumberOfElem(master_job_list),
               lGetNumberOfElem(master_exechost_list),
               lGetNumberOfElem(master_centry_list),
               lGetNumberOfElem(copy.acl_list),
               lGetNumberOfElem(copy.dept_list),
               lGetNumberOfElem(master_project_list),
               lGetNumberOfElem(master_ckpt_list),
               lGetNumberOfElem(master_user_list),
               lGetNumberOfElem(master_project_list),
               lGetNumberOfElem(master_rqs_list),
               lGetNumberOfElem(master_ar_list),
               lGetNumberOfNodes(NULL, master_sharetree_list, STN_children),
               lGetNumberOfLeafs(NULL, master_sharetree_list, STN_children)
            ));

            sge_rebuild_job_category(master_job_list, master_userset_list,
                                        master_project_list, master_rqs_list);

            PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7);
            prof_init = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL);
            PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7);

            sge_before_dispatch(evc);

            /* prepare data for the scheduler itself */
            copy.host_list = lCopyList("", master_exechost_list);

            /*
             * Within the scheduler we do only need QIs
             */
            {
               lListElem *cqueue = NULL;
               lEnumeration *what_queue3 = NULL;

               for_each(cqueue, master_cqueue_list) {
                  lList *qinstance_list = lGetList(cqueue, CQ_qinstances);
                  lList *t;

                  if (!qinstance_list) {
                     continue;
                  }

                  /* all_queue_list contains all queue instances with state and full queue name only */
                  if (!what_queue3) {
                     what_queue3 = lWhat("%T(%I%I)", lGetListDescr(qinstance_list), QU_full_name, QU_state);
                  }
                  t = lSelect("t", qinstance_list, NULL, what_queue3);
                  if (t) {
                     if (copy.all_queue_list == NULL) {
                        copy.all_queue_list = lCreateList("all", lGetListDescr(t));
                     }
                     lAppendList(copy.all_queue_list, t);
                     lFreeList (&t);
                  }

                  t = lSelect("t", qinstance_list, where_what.where_queue, where_what.what_queue2);
                  if (t) {
                     if (copy.queue_list == NULL) {
                        copy.queue_list = lCreateList("enabled", lGetListDescr(t));
                     }
                     lAppendList(copy.queue_list, t);
                     lFreeList (&t);
                  }

                  t = lSelect("t", qinstance_list, where_what.where_queue2, where_what.what_queue2);
                  if (t) {
                     if (copy.dis_queue_list == NULL) {
                        copy.dis_queue_list = lCreateList("disabled", lGetListDescr(t));
                     }
                     lAppendList(copy.dis_queue_list, t);
                     lFreeList (&t);
                  }
               }
               if (what_queue3) {
                  lFreeWhat(&what_queue3);
               }
            }

            if (sconf_is_job_category_filtering()) {
               copy.job_list = sge_category_job_copy(copy.queue_list, &orders, evc->monitor_next_run);
            } else {
               copy.job_list = lCopyList("", master_job_list);
            }

            /* no need to copy these lists, they are read only used */
            copy.centry_list = master_centry_list;
            copy.ckpt_list = master_ckpt_list;
            copy.hgrp_list = master_hgrp_list;

            /* these lists need to be copied because they are modified during scheduling run */
            copy.share_tree = lCopyList("", master_sharetree_list);
            copy.pe_list = lCopyList("", master_pe_list);
            copy.user_list = lCopyList("", master_user_list);
            copy.project_list = lCopyList("", master_project_list);
            copy.rqs_list = lCopyList("", master_rqs_list);
            copy.ar_list = lCopyList("", master_ar_list);

            /* report number of reduced and raw (in brackets) lists */
            DPRINTF(("Q:%d, AQ:%d J:%d(%d), H:%d(%d), C:%d, A:%d, D:%d, P:%d, CKPT:%d,"
                     " US:%d, PR:%d, RQS:%d, AR:%d, S:nd:%d/lf:%d \n",
               lGetNumberOfElem(copy.queue_list),
               lGetNumberOfElem(copy.all_queue_list),
               lGetNumberOfElem(copy.job_list),
               lGetNumberOfElem(master_job_list),
               lGetNumberOfElem(copy.host_list),
               lGetNumberOfElem(master_exechost_list),
               lGetNumberOfElem(copy.centry_list),
               lGetNumberOfElem(copy.acl_list),
               lGetNumberOfElem(copy.dept_list),
               lGetNumberOfElem(copy.pe_list),
               lGetNumberOfElem(copy.ckpt_list),
               lGetNumberOfElem(copy.user_list),
               lGetNumberOfElem(copy.project_list),
               lGetNumberOfElem(copy.rqs_list),
               lGetNumberOfElem(copy.ar_list),
               lGetNumberOfNodes(NULL, copy.share_tree, STN_children),
               lGetNumberOfLeafs(NULL, copy.share_tree, STN_children)
            ));

            if (getenv("SGE_ND")) {
               printf("Q:%d, AQ:%d J:%d(%d), H:%d(%d), C:%d, A:%d, D:%d, "
                  "P:%d, CKPT:%d, US:%d, PR:%d, RQS:%d, AR:%d, S:nd:%d/lf:%d \n",
                  lGetNumberOfElem(copy.queue_list),
                  lGetNumberOfElem(copy.all_queue_list),
                  lGetNumberOfElem(copy.job_list),
                  lGetNumberOfElem(master_job_list),
                  lGetNumberOfElem(copy.host_list),
                  lGetNumberOfElem(master_exechost_list),
                  lGetNumberOfElem(copy.centry_list),
                  lGetNumberOfElem(copy.acl_list),
                  lGetNumberOfElem(copy.dept_list),
                  lGetNumberOfElem(copy.pe_list),
                  lGetNumberOfElem(copy.ckpt_list),
                  lGetNumberOfElem(copy.user_list),
                  lGetNumberOfElem(copy.project_list),
                  lGetNumberOfElem(copy.rqs_list),
                  lGetNumberOfElem(copy.ar_list),
                  lGetNumberOfNodes(NULL, copy.share_tree, STN_children),
                  lGetNumberOfLeafs(NULL, copy.share_tree, STN_children)
                 );
            } else {
               schedd_log("-------------START-SCHEDULER-RUN-------------", NULL, evc->monitor_next_run);
            }

            PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7);
            prof_copy = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL);
            PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7);

            scheduler_method(evc, &answer_list, &copy, &orders);
            answer_list_output(&answer_list);

            PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7);
            prof_run = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL);
            PROF_START_MEASUREMENT(SGE_PROF_CUSTOM7);

            /* .. which gets deleted after using */
            lFreeList(&(copy.host_list));
            lFreeList(&(copy.queue_list));
            lFreeList(&(copy.dis_queue_list));
            lFreeList(&(copy.all_queue_list));
            lFreeList(&(copy.job_list));
            lFreeList(&(copy.acl_list));
            lFreeList(&(copy.dept_list));
            lFreeList(&(copy.pe_list));
            lFreeList(&(copy.share_tree));
            lFreeList(&(copy.user_list));
            lFreeList(&(copy.project_list));
            lFreeList(&(copy.rqs_list));
            lFreeList(&(copy.ar_list));

            PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM7);
            prof_free = prof_get_measurement_wallclock(SGE_PROF_CUSTOM7, true, NULL);

            /* 
             * need to sync with event master thread
             * if schedd configuration changed then settings in evm can be adjusted
             */
            if (sconf_is_new_config()) {
               /* set scheduler interval / event delivery interval */
               u_long32 interval = sconf_get_schedule_interval();
               if (evc->ec_get_edtime(evc) != interval) {
                  evc->ec_set_edtime(evc, interval);
               }

               /* set job / ja_task event flushing */
               set_job_flushing(evc);

               /* no need to ec_commit here - we do it when resetting the busy state */

               /* now we handled the new schedd config - no need to do it twice */
               sconf_reset_new_config();
            }

            /* block till master handled all GDI orders */
            sge_schedd_block_until_orders_processed(evc->get_gdi_ctx(evc), NULL);
            schedd_order_destroy();

            /*
             * Stop profiling for "schedd run total" and the subcategories
             */
            PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM6);
            prof_total = prof_get_measurement_wallclock(SGE_PROF_CUSTOM6, true, NULL);

            if (prof_is_active(SGE_PROF_CUSTOM6)) {
               PROFILING((SGE_EVENT, "PROF: schedd run took: %.3f s (init: %.3f s, copy: %.3f s, "
                          "run:%.3f, free: %.3f s, jobs: %d, categories: %d/%d)",
                           prof_total, prof_init, prof_copy, prof_run, prof_free,
                           lGetNumberOfElem(*object_type_get_master_list(SGE_TYPE_JOB)), sge_category_count(),
                           sge_cs_category_count() ));
            }
            if (getenv("SGE_ND") != NULL) {
               printf("--------------STOP-SCHEDULER-RUN-------------\n");
            } else {
               schedd_log("--------------STOP-SCHEDULER-RUN-------------", NULL, evc->monitor_next_run);
            }

            thread_output_profiling("scheduler thread profiling summary:\n", &next_prof_output);

            sge_monitor_output(&monitor);
         }

         /* reset the busy state */
         evc->ec_set_busy(evc, 0);
         evc->ec_commit(evc, NULL);

         /* stop logging into schedd_runlog (enabled via -tsm) */
         evc->monitor_next_run = false;

         /*
          * pthread cancelation point
          *
          * sge_scheduler_cleanup_thread() is the last function which should
          * be called so it is pushed first
          */
         pthread_cleanup_push(sge_scheduler_cleanup_thread, (void *) &ctx);
         pthread_cleanup_push((void (*)(void *))sge_scheduler_cleanup_monitor,
                              (void *)&monitor);
         pthread_cleanup_push((void (*)(void *))sge_scheduler_cleanup_event_client,
                              (void *)evc);
         cl_thread_func_testcancel(thread_config);
         pthread_cleanup_pop(execute);
         pthread_cleanup_pop(execute);
         pthread_cleanup_pop(execute);
         DPRINTF(("passed cancelation point\n"));
      }
Beispiel #7
0
/*-------------------------------------------------------------------------*/
lList* qmonGet2xN(
Widget w,
lDescr *dp,
int field1,
int field2 
) {
   lList *lp = NULL;
   lListElem *ep;
   int row;
   int max_rows;
   char *col1, *col2;

   DENTER(GUI_LAYER, "qmonGet2xN");

   XtVaGetValues(w, XmNrows, &max_rows, NULL);
   
   for (row=0; row<max_rows; row++) {
      col1 = XbaeMatrixGetCell(w, row, 0);
      col2 = XbaeMatrixGetCell(w, row, 1);
      if (col1 && col1[0] != '\0') {
         if (!lp)
            lp = lCreateList(XtName(w), dp);
         ep = lCreateElem(dp);
         lAppendElem(lp, ep);

         /*
         ** the first field in the column can be host or string
         */

         switch(lGetType(lGetListDescr(lp), field1)) {
            case lStringT:
               lSetString(ep, field1, col1 ? col1 : "");
               break;
            case lHostT:
               lSetHost(ep, field1, col1 ? col1 : "");
               break;
         }

         /*
         ** the second field can be of different type
         */
         switch(lGetType(lGetListDescr(lp), field2)) {
            case lStringT: 
               lSetString(ep, field2, col2 ? col2 : "" );
               break;
            case lHostT:
               lSetHost(ep, field2, col2 ? col2 : "");
               break;
            case lUlongT:
               lSetUlong(ep, field2, col2 ? atoi(col2) : 0);
               break;
            case lDoubleT:
               lSetDouble(ep, field2, col2 ? atof(col2) : 0.0);
               break;
         }   
      }
      else
         continue;
   }

   DEXIT;
   return lp;
}
Beispiel #8
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;
}
Beispiel #9
0
/*-------------------------------------------------------------------------*/
lList* qmonGetNxN(
Widget w,
lDescr *dp,
int num_fields,
...
) {
   lList *lp = NULL;
   lListElem *ep;
   int i, row;
   int max_rows;
   va_list ap;
   char **col;
   int *field;

   DENTER(GUI_LAYER, "qmonGetNxN");

   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 (row=0; row<max_rows; row++)
   {
      memset(col, 0, num_fields*sizeof(char *));

      for(i=0; i<num_fields; i++)
         col[i] = XbaeMatrixGetCell(w, row, i);

      if (col[0] && col[0][0] != '\0')
      {
         if (!lp)
            lp = lCreateList(XtName(w), dp);

         ep = lCreateElem(dp);
         lAppendElem(lp, ep);

         /*
          * retrieve values from columns
          */

         for(i=0; i<num_fields; i++)
         {
            switch(lGetType(lGetListDescr(lp), field[i]))
            {
               case lStringT: 
                  lSetString(ep, field[i], col[i] ? col[i] : "" );
                  break;
               case lHostT:
                  lSetHost(ep, field[i], col[i] ? col[i] : "");
                  break;
               case lUlongT:
                  lSetUlong(ep, field[i], col[i] ? atoi(col[i]) : 0);
                  break;
               case lDoubleT:
                  lSetDouble(ep, field[i], col[i] ? atof(col[i]) : 0.0);
                  break;
            }
         }
      }
      else
         continue;
   }

   va_end(ap);
   free(field);
   free(col);

   DEXIT;
   return lp;
}
Beispiel #10
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 #11
0
/****** Eventmirror/job/job_update_master_list() *****************************
*  NAME
*     job_update_master_list() -- update the master list of jobs
*
*  SYNOPSIS
*     bool job_update_master_list(sge_object_type type,
*                                     sge_event_action action,
*                                     lListElem *event, void *clientdata)
*
*  FUNCTION
*     Update the global master list of jobs
*     based on an event.
*     The function is called from the event mirroring interface.
*
*     A jobs array tasks are not updated by this function,
*     as they are maintained by separate events.
*     In addition, some scheduler specific attributes, that
*     are only used in scheduler, are not updated.
*
*  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
*     Eventmirror/sge_mirror_update_master_list()
*     Eventmirror/job/job_update_master_list_usage()
*******************************************************************************/
sge_callback_result
job_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;
   const lDescr *list_descr;
   u_long32 job_id;
   lListElem *job = NULL;
   lList *ja_tasks = NULL;

   char id_buffer[MAX_STRING_SIZE];
   dstring id_dstring;

   DENTER(TOP_LAYER, "job_update_master_list");

   sge_dstring_init(&id_dstring, id_buffer, MAX_STRING_SIZE);

   list = sge_master_list(object_base, SGE_TYPE_JOB);
   list_descr = lGetListDescr(lGetList(event, ET_new_version)); 
   job_id = lGetUlong(event, ET_intkey);
   job = job_list_locate(*list, job_id);

   if (action == SGE_EMA_MOD) {
      u_long32 event_type = lGetUlong(event, ET_type);

      if (job == NULL) {
         ERROR((SGE_EVENT, MSG_JOB_CANTFINDJOBFORUPDATEIN_SS,
                job_get_id_string(job_id, 0, NULL, &id_dstring), "job_update_master_list"));
         DRETURN(SGE_EMA_FAILURE);
      }

      if (event_type == sgeE_JOB_USAGE || event_type == sgeE_JOB_FINAL_USAGE ) {
         /* special handling needed for JOB_USAGE and JOB_FINAL_USAGE events.
         * they are sent for jobs, ja_tasks and pe_tasks and only contain
         * the usage list.
         * Preferable would probably be to send MOD events for the different
         * object types.
         */
         bool ret = job_update_master_list_usage(*list, event);
         DRETURN(ret?SGE_EMA_OK:SGE_EMA_FAILURE);
      } else {
         /* this is the true modify event.
          * we may not update several fields:
          * - JB_ja_tasks is the task list - it is maintained by JATASK events
          * - JB_host and JB_category are scheduler internal attributes
          *   they may not be overwritten.
          *   Better would be to move them from JB_Type to some scheduler specific
          *   object.
          */

          lListElem *modified_job;

          modified_job = lFirst(lGetList(event, ET_new_version));
          if(job != NULL && modified_job != NULL) {
            /* we want to preserve the old ja_tasks, since job update events to not contain them */
            lXchgList(job, JB_ja_tasks, &ja_tasks);
            lSetHost(modified_job, JB_host, lGetHost(job, JB_host));
            lSetRef(modified_job, JB_category, lGetRef(job, JB_category));
          }
      }
   }

   if (sge_mirror_update_master_list(list, list_descr, job, job_get_id_string(job_id, 0, NULL, &id_dstring), action, event) != SGE_EM_OK) {
      lFreeList(&ja_tasks);
      DRETURN(SGE_EMA_FAILURE);
   }

   /* restore ja_task list after modify event */
   if (action == SGE_EMA_MOD && ja_tasks != NULL) {
      /* we have to search the replaced job */
      job = job_list_locate(*list, job_id);
      if(job == NULL) {
         ERROR((SGE_EVENT, MSG_JOB_CANTFINDJOBFORUPDATEIN_SS,
                job_get_id_string(job_id, 0, NULL, &id_dstring), "job_update_master_list"));
         lFreeList(&ja_tasks);
         DRETURN(SGE_EMA_FAILURE);
      }

      lXchgList(job, JB_ja_tasks, &ja_tasks);
      lFreeList(&ja_tasks);
   }

   DRETURN(SGE_EMA_OK);
}
Beispiel #12
0
/****** cull/db/lJoin() *******************************************************
*  NAME
*     lJoin() -- Joins two lists together
*
*  SYNOPSIS
*     lList* lJoin(const char *name, int nm0, const lList *lp0, 
*                  const lCondition *cp0, const lEnumeration *enp0, 
*                  int nm1, const lList *lp1, const lCondition *cp1, 
*                  const lEnumeration *enp1) 
*
*  FUNCTION
*     Returns a new list joining together the lists 'lp0' and 'lp1'
*     For the join only these 'lines' described in condition 'cp0'
*     and 'cp1' are used.
*     The new list gets only these members described in 'enp0' and
*     'enp1'. NULL means every member of this list.
*     The list gets 'name' as listname.
*
*  INPUTS
*     const char *name         - name of new list 
*     int nm0                  - 
*     const lList *lp0         - first list 
*     const lCondition *cp0    - selects rows of first list 
*     const lEnumeration *enp0 - selects column of first list 
*     int nm1                  - 
*     const lList *lp1         - second list 
*     const lCondition *cp1    - selects rows of second list 
*     const lEnumeration *enp1 - selects column of seconf list 
*
*  RESULT
*     lList* - Joined list 
******************************************************************************/
lList *lJoin(const char *name, int nm0, const lList *lp0, 
             const lCondition *cp0, const lEnumeration *enp0, int nm1,
             const lList *lp1, const lCondition *cp1, const lEnumeration *enp1)
{
   lListElem *ep0, *ep1;
   lListElem *ep;
   lList *dlp = NULL;
   lDescr *dp;
   int lp0_pos = 0, lp1_pos = 0;
   int i, j;
   int needed;

   DENTER(CULL_LAYER, "lJoin");

   if (!lp0 || !lp1 || !name || !enp0 || !enp1) {
      LERROR(LENULLARGS);
      DEXIT;
      return NULL;
   }

   if (nm1 != NoName) {
      if ((lp0_pos = lGetPosInDescr(lGetListDescr(lp0), nm0)) < 0) {
         LERROR(LENAMENOT);
         DEXIT;
         return NULL;
      }
      if ((lp1_pos = lGetPosInDescr(lGetListDescr(lp1), nm1)) < 0) {
         LERROR(LENAMENOT);
         DEXIT;
         return NULL;
      }

      if (mt_get_type(lp0->descr[lp0_pos].mt) != mt_get_type(lp1->descr[lp1_pos].mt) ||
          mt_get_type(lp0->descr[lp0_pos].mt) == lListT) {
         LERROR(LEDIFFDESCR);
         DEXIT;
         return NULL;
      }
   }

   /* the real join ?! */
   if (!(dp = lJoinDescr(lGetListDescr(lp0), lGetListDescr(lp1), enp0, enp1))) {
      LERROR(LEJOINDESCR);
      DEXIT;
      return NULL;
   }
   if (!(dlp = lCreateList(name, dp))) {
      LERROR(LECREATELIST);
      sge_free(&dp);
      DEXIT;
      return NULL;
   }
   /* free dp it has been copied by lCreateList */
   sge_free(&dp);

   for (i = 0, ep0 = lp0->first; i < lp0->nelem; i++, ep0 = ep0->next) {
      if (!lCompare(ep0, cp0))
         continue;
      for (j = 0, ep1 = lp1->first; j < lp1->nelem; j++, ep1 = ep1->next) {
         if (!lCompare(ep1, cp1))
            continue;
         if (nm1 != NoName) {   /* in this case take it always */
            /* This is a comparison of the join fields nm0 , nm1 */
            switch (mt_get_type(lp0->descr[lp0_pos].mt)) {
            case lIntT:
               needed = (ep0->cont[lp0_pos].i == ep1->cont[lp1_pos].i);
               break;
            case lUlongT:
               needed = (ep0->cont[lp0_pos].ul == ep1->cont[lp1_pos].ul);
               break;
            case lStringT:
               needed = !strcmp(ep0->cont[lp0_pos].str, ep1->cont[lp1_pos].str);
               break;
            case lHostT:
               needed = !strcmp(ep0->cont[lp0_pos].str, ep1->cont[lp1_pos].str);
               break;
            case lLongT:
               needed = (ep0->cont[lp0_pos].l == ep1->cont[lp1_pos].l);
               break;
            case lFloatT:
               needed = (ep0->cont[lp0_pos].fl == ep1->cont[lp1_pos].fl);
               break;
            case lDoubleT:
               needed = (ep0->cont[lp0_pos].db == ep1->cont[lp1_pos].db);
               break;
            case lCharT:
               needed = (ep0->cont[lp0_pos].c == ep1->cont[lp1_pos].c);
               break;
            case lBoolT:
               needed = (ep0->cont[lp0_pos].b == ep1->cont[lp1_pos].b);
               break;
            case lRefT:
               needed = (ep0->cont[lp0_pos].ref == ep1->cont[lp1_pos].ref);
               break;
            default:
               unknownType("lJoin");
               DEXIT;
               return NULL;
            }
            if (!needed)
               continue;
         }
         if (!(ep = lJoinCopyElem(dlp->descr, ep0, enp0, ep1, enp1))) {
            LERROR(LEJOINCOPYELEM);
            lFreeList(&dlp);
            DEXIT;
            return NULL;
         }
         else {
            if (lAppendElem(dlp, ep) == -1) {
               LERROR(LEAPPENDELEM);
               lFreeList(&dlp);
               DEXIT;
               return NULL;
            }
         }
      }
   }

   /* RETURN AN EMPTY LIST OR NULL THAT'S THE QUESTION */

   if (lGetNumberOfElem(dlp) == 0) {
      lFreeList(&dlp);
   }

   DEXIT;
   return dlp;
}
Beispiel #13
0
/****** cull/db/lJoinSublist() ************************************************
*  NAME
*     lJoinSublist() -- Join a list with one of its sublists 
*
*  SYNOPSIS
*     lList* lJoinSublist(const char *name, 
*                         int nm0, 
*                         const lList *lp, 
*                         const lCondition *cp0, 
*                         const lEnumeration *enp0, 
*                         const lDescr *sldp, 
*                         const lCondition *cp1, 
*                         const lEnumeration *enp1) 
*
*  FUNCTION
*     Joins a list and one of its sublists together. The other 
*     parameters are equal to them from lJoin(). In the enumeration
*     'enp0' the sublist field neither may be selected nor 'enp0'
*     may be NULL. 
*
*  INPUTS
*     const char *name         - new list name 
*     int nm0                  - 
*     const lList *lp          - list 
*     const lCondition *cp0    - selects rows within 'lp' 
*     const lEnumeration *enp0 - selects columns within 'lp' 
*     const lDescr *sldp       - sublist descriptor pointer 
*     const lCondition *cp1    - selects rows within 'sldp' 
*     const lEnumeration *enp1 - selects columns within 'enp1' 
*
*  RESULT
*     lList* - Joined list 
******************************************************************************/
lList *lJoinSublist(const char *name, int nm0, const lList *lp, 
                    const lCondition *cp0, const lEnumeration *enp0,
                    const lDescr *sldp, const lCondition *cp1, 
                    const lEnumeration *enp1) 
{
   lList *dlp, *tlp, *joinedlist, *sublist;
   lListElem *ep;
   lDescr *dp; 
   const lDescr *tdp;
   int i, pos;

   DENTER(CULL_LAYER, "lJoinSublist");

   /* check different pointers */
   if (!name || !lp || !enp0 || !sldp || !enp1) {
      LERROR(LENULLARGS);
      DEXIT;
      return NULL;
   }

   /* make sure that nm0 is a sublist field of lp */
   if (!(tdp = lGetListDescr(lp))) {
      LERROR(LEDESCRNULL);
      DEXIT;
      return NULL;
   }
   if ((pos = lGetPosInDescr(tdp, nm0)) < 0) {
      LERROR(LENAMENOT);
      DEXIT;
      return NULL;
   }

   if (mt_get_type(tdp[pos].mt) != lListT) {
      LERROR(LEINCTYPE);
      DEXIT;
      return NULL;
   }

   /* is nm0 enumerated in enp0 ? */
   if (enp0[0].pos == WHAT_ALL) {
      LERROR(LEFALSEFIELD);
      DEXIT;
      return NULL;
   }
   for (i = 0; enp0[i].nm != NoName; i++)
      if (enp0[i].nm == nm0) {
         LERROR(LEFALSEFIELD);
         DEXIT;
         return NULL;
      }

   /* create destination list */
   if (!(dp = lJoinDescr(lGetListDescr(lp), sldp, enp0, enp1))) {
      LERROR(LEJOINDESCR);
      DEXIT;
      return NULL;
   }
   if (!(dlp = lCreateList(name, dp))) {
      sge_free(&dp);
      LERROR(LECREATELIST);
      DEXIT;
      return NULL;
   }
   /* free dp it has been copied in lCreateList */
   sge_free(&dp);

   /* create a temporary list to be used by lJoin */
   if (!(tlp = lCreateList("lJoinSublist: tlp", lGetListDescr(lp)))) {
      lFreeList(&dlp);
      LERROR(LECREATELIST);
      DEXIT;
      return NULL;
   }

   for_each_where(ep, lp, cp0) {
      /* is there a sublist for the join */
      if ((sublist = lGetList(ep, nm0)) != NULL) {

         /* put each element in the tlp to be used by lJoin */
         if (lAppendElem(tlp, lCopyElem(ep)) == -1) {
            lFreeList(&tlp);
            lFreeList(&dlp);
            LERROR(LEAPPENDELEM);
            DEXIT;
            return NULL;
         }

         /* join the tlp with one element together with its sublist */
         joinedlist = lJoin("lJoinSublist: joinedlist", nm0, tlp, NULL, enp0,
                            NoName, sublist, cp1, enp1);

         if (!joinedlist) {
            lFreeList(&tlp);
            lFreeList(&dlp);
            LERROR(LEJOIN);
            DEXIT;
            return NULL;
         }

         /* joinedlist is freed in lAddList */
         if (joinedlist && lAddList(dlp, &joinedlist) == -1) {
            LERROR(LEADDLIST);
            lFreeList(&tlp);
            lFreeList(&dlp);
            DEXIT;
            return NULL;
         }

         /* dechain the only element from tlp and free it (copy) */
         lRemoveElem(tlp, &(tlp->first));
      }
   }
   /* temporary list has to be freed */
   lFreeList(&tlp);

   /* RETURN AN EMPTY LIST OR NULL THAT'S THE QUESTION */

   if (lGetNumberOfElem(dlp) == 0) {
      lFreeList(&dlp);
   }

   DEXIT;
   return dlp;
}
Beispiel #14
0
int main(int argc, char *argv[])
{
   lList *queuelist = NULL, *joblist = NULL;

   enum {
      MATCH_REQUEST,
      LOOP_JOBS_QUEUES
/*                              SUBWHERE */
   };
   int scene, fulfilled, numdiddeldum;

   lList *erglist = NULL;
   lListElem *job, *queue;
   lCondition *where = NULL;

   lEnumeration *w0, *w1, *nothing, *all;
   lList *queuecomplexes = NULL, *attributes = NULL;
   lListElem *attribute, *request;
   const char *operator;

   DENTER_MAIN(TOP_LAYER, "example2");

   if (argc != 3)
      usage();

   sscanf(argv[1], "%d", &scene);
   sscanf(argv[2], "%d", &numdiddeldum);

   /* neccessary for comfortable output  */
   lInit(nmv);

   queuelist = buildQueueList();
   printf("\n\nQUEUELIST\n\n");
   lWriteList(queuelist);

   COMPLEXLIST = buildComplexList();
   printf("\n\nCOMPLEXLIST\n\n");
   lWriteList(COMPLEXLIST);

   joblist = buildJobList(numdiddeldum);
   printf("\n\nJOBLIST\n\n");
   lWriteList(joblist);

   printf("\n******** BEGIN PROCESSING *********\n\n");

   switch (scene) {

   case MATCH_REQUEST:

      /* 
         find for each job in the joblist all queues that 
         suffer the request of this job 
         ( implemented with quick list functions )
       */

      for_each(job, joblist) {

         printf("\n-------------------------------"
                "-------------------------------\n");
         printf("*** job %s may get started in the following queues ***\n\n",
                lGetString(job, J_name));

         for_each(queue, queuelist) {
            if (matchRequest(lGetList(queue, Q_complexname),
                             lGetList(job, J_hardrequest))) {
               if (!erglist)
                  if (!(erglist = lCreateList("erglist", QueueT))) {
                     printf("case MATCH_REQUEST: lCreateList"
                            " failure\n");
                     exit(-1);
                  }
               lAppendElem(erglist, lCopyElem(queue));
            }
         }
         printf("\n\n**** ERGLIST ****\n\n");
         if (erglist) {
            lWriteList(erglist);
            lFreeList(&erglist);
            erglist = NULL;
         }
      }

      break;

   case LOOP_JOBS_QUEUES:

      /* 
         find for each job in the joblist all queues that 
         suffer the request of this job 
         ( implemented with mighty database-like functions )
       */

      for_each(job, joblist) {

         printf("\n--------------------------------------------------------------\n");
         printf("*** job %s may get started in the following queues ***\n\n",
                lGetString(job, J_name));

         for_each(queue, queuelist) {

            /*
               build a list of the complexes of the queue

               therefore: build a subset of the complex list 
               with the queues complex name list as a selector

               join the complex name list of the queue      
               ( join field: N_complexname) 
               with the global complex list                                         
               ( join field: C_name )

               select nothing from the queue's complex name list (w0)
               and only the attributes of the global complex list (w1)

               every valid combination is needed, so the 
               where parameter is NULL for both lists 
             */

            w0 = lWhat("%T(NONE)", ComplexNameT);       /* NIX */
            w1 = lWhat("%T(%I)", ComplexT, C_attribute);

            queuecomplexes = lJoin("queuecomplexes",
                 N_complexname, lGetList(queue, Q_complexname), NULL, w0,
                                   C_name, COMPLEXLIST, NULL, w1);

            lFreeWhat(&w0);
            lFreeWhat(&w1);

            /* 
               try to find a hard request of this job 
               that is not fulfilled by the queue's complexes
             */
            fulfilled = 1;

            for_each(request, lGetList(job, J_hardrequest)) {

               /* 
                  build a flat complex attribute list with only
                  these attributes of the request

                  this produces a attribute list of all complexes 
                */

               nothing = lWhat("%T(NONE)", lGetListDescr(queuecomplexes));
               all = lWhat("%T(ALL)", ComplexAttributeT);
               where = lWhere("%T( %I == %s )", ComplexAttributeT,
                              A_name,
                              lGetString(request, R_name));

               attributes = lJoinSublist("attributelist",
                              C_attribute, queuecomplexes, NULL, nothing,
                                         ComplexAttributeT, where, all);

               lFreeWhere(&where);
               lFreeWhat(&nothing);
               lFreeWhat(&all);

               /* 
                  if we get an empty list then the queue has 
                  no complex fulfilling the request of this job
                */
               /* 
                  right now the lJoinSublist function returns
                  an empty list (no elements) if there was no sublist
                */
               if (lGetNumberOfElem(attributes) == 0) {
                  fulfilled = 0;
                  break;        /* leave request loop */
               }

               /* 
                  if there are attributes the values of at least one
                  complex of the queue must fulfill the request
                */
               for_each(attribute, attributes) {

                  operator = lGetString(request, R_operator);

                  if (strcmp(operator, "==") == 0) {
                     fulfilled = (!strcmp(
                                          lGetString(attribute, A_value),
                                          lGetString(request, R_value)));

                  }
                  else if (strcmp(operator, "!=") == 0) {
                     fulfilled = (strcmp(
                                           lGetString(attribute, A_value),
                                           lGetString(request, R_value)));

                  }             /* else if .. ( for all operators ) */

                  if (fulfilled)
                     break;     /* leave attribute loop */
               }