/* ----------------------------------------

   add a string value to the load report list lpp

*/
int sge_add_str2load_report(lList **lpp, const char *name, const char *value, const char *host)
{
   lListElem *ep = NULL, *search_ep = NULL;
   const void *iterator = NULL;

   DENTER(BASIS_LAYER, "sge_add_str2load_report");

   if (lpp == NULL || name == NULL || value == NULL || host == NULL) {
      DRETURN(-1);
   }

   if (*lpp != NULL) {
      search_ep = lGetElemHostFirst(*lpp, LR_host, host, &iterator);
      while (search_ep != NULL) {
         DPRINTF(("---> %s\n", lGetString(search_ep, LR_name)));
         if (strcmp(lGetString(search_ep, LR_name), name) == 0) {
            ep = search_ep;
            break;
         }
         search_ep = lGetElemHostNext(*lpp, LR_host, host, &iterator);
      }
   }
   
   if (ep == NULL) {
      DPRINTF(("adding new load variable %s for host %s\n", name, host));
      ep = lAddElemStr(lpp, LR_name, name, LR_Type);
      lSetHost(ep, LR_host, host);
      lSetUlong(ep, LR_global, (u_long32)(strcmp(host, SGE_GLOBAL_NAME) == 0 ? 1 : 0));
      lSetUlong(ep, LR_static, sge_is_static_load_value(name));
   }

   lSetString(ep, LR_value, value);

   DPRINTF(("load value %s for host %s: %s\n", name, host, value)); 

   DRETURN(0);
}
bool test_lWhat_lSelect(void)
{
   bool ret = true;
   lEnumeration *what = lWhat("%T(%I %I -> %T( %I %I -> %T (%I %I %I %I) %I %I) %I -> %T(%I) %I)",
                              TEST_Type, 
                                 TEST_int, 
                                 TEST_list, TEST1_Type, 
                                    TEST1_int,
                                    TEST1_list, TEST_Type,
                                       TEST_int,
                                       TEST_list,
                                       TEST_object,
                                       TEST_string,
                                    TEST1_object,
                                    TEST1_string,
                                 TEST_object, TEST1_Type, 
                                    TEST1_string,
                                 TEST_string);
   lListElem *elem;
   lListElem *elem1;
   lList *list = lCreateList("", TEST_Type);
   lList *list1 = NULL;
   int i;

   elem = lCreateElem(TEST_Type); 
   lSetInt(elem, TEST_int, 0);
   lSetHost(elem, TEST_host, "zero");
   lSetString(elem, TEST_string, "zero");
   lSetFloat(elem, TEST_float, 0);
   lSetDouble(elem, TEST_double, 0); 
   lSetChar(elem, TEST_char, 'z');
   lSetLong(elem, TEST_long, 0);
   lSetUlong(elem, TEST_ulong, 0);
   lSetBool(elem, TEST_bool, false);

   elem1 = lCreateElem(TEST1_Type); 
   lSetInt(elem1, TEST1_int, 1);
   lSetHost(elem1, TEST1_host, "one");
   lSetString(elem1, TEST1_string, "one");
   lSetFloat(elem1, TEST1_float, 1);
   lSetDouble(elem1, TEST1_double, 1); 
   lSetChar(elem1, TEST1_char, 'o');
   lSetLong(elem1, TEST1_long, 1);
   lSetUlong(elem1, TEST1_ulong, 1);
   lSetBool(elem1, TEST1_bool, true);

   for (i = 0; i < 5; i++) {
      lList *tmp_list = lCreateList("", TEST1_Type);
      lListElem *tmp_elem = lCopyElem(elem);
      int j;

      for (j = 0; j < 5; j++) {
         lList *tmp_list1 = lCreateList("", TEST_Type);
         lListElem *tmp_elem1 = lCopyElem(elem);
         int k;
   
         for (k = 0; k < 5; k++) {
            lList *tmp_list2 = lCreateList("", TEST1_Type);
            lListElem *tmp_elem2 = lCopyElem(elem);

            lSetList(tmp_elem2, TEST_list, tmp_list2);
            lAppendElem(tmp_list1, tmp_elem2);
         }

         lSetList(tmp_elem1, TEST_list, tmp_list1);
         lAppendElem(tmp_list, tmp_elem1);
      }

      lSetList(tmp_elem, TEST_list, tmp_list);
      lAppendElem(list, tmp_elem);
   }

   list1 = lSelect("", list, NULL, what);

   /* EB: Replace this function */
#if 0
   lWriteListTo(list1, stderr);
#endif

   lFreeWhat(&what);
   lFreeElem(&elem);
   lFreeElem(&elem1);
   lFreeList(&list);
   lFreeList(&list1);

   return ret;
}
/****** 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 #4
0
/****** gdi/sge/sge_qexecve() ************************************************
*  NAME
*     sge_qexecve() -- start a task in a tightly integrated par. job
*
*  SYNOPSIS
*     sge_tid_t sge_qexecve(const char *hostname, const char *queuename,
*                           const char *cwd, const lList *environment
*                           const lList *path_aliases)
*
*  FUNCTION
*     Starts a task in a tightly integrated job.
*     Builds a job object describing the task,
*     connects to the commd on the targeted execution host,
*     deliveres the job object and waits for an answer.
*     The answer from the execution daemon on the execution host
*     contains a task id that is returned to the caller of the function.
*
*  INPUTS
*     const char *hostname - name of the host on which to start the task
*     const lList *environment  - list containing environment variable
*                            settings for the task that override the
*                            default environment
*     const lList *path_aliases - optional a path alias list
*
*  RESULT
*     sge_tid_t - the task id, if the task can be executed,
*                 a value <= 0 indicates an error.
*
*  NOTES
*     MT-NOTE: sge_qexecve() is not MT safe
******************************************************************************/
sge_tid_t sge_qexecve(sge_gdi_ctx_class_t *ctx,
                      const char *hostname, const char *queuename,
                      const char *cwd, const lList *environment,
                      const lList *path_aliases)
{
    char myname[256];
    const char *s;
    int ret, uid;
    sge_tid_t tid = NULL;
    lListElem *petrep;
    lListElem *rt;
    sge_pack_buffer pb;
    u_long32 jobid, jataskid;
    u_long32 dummymid = 0;
    const char *env_var_name = "SGE_TASK_ID";

    DENTER(TOP_LAYER, "sge_qexecve");

    if (hostname == NULL) {
        sprintf(lasterror, MSG_GDI_INVALIDPARAMETER_SS, "sge_qexecve", "hostname");
        DRETURN(NULL);
    }

    /* resolve user */
    if (sge_uid2user((uid=getuid()), myname, sizeof(myname)-1, MAX_NIS_RETRIES)) {
        sprintf(lasterror, MSG_GDI_RESOLVINGUIDTOUSERNAMEFAILED_IS ,
                uid, strerror(errno));
        DRETURN(NULL);
    }

    if ((s=getenv("JOB_ID")) == NULL) {
        sprintf(lasterror, MSG_GDI_MISSINGINENVIRONMENT_S, "JOB_ID");
        DRETURN(NULL);
    }

    if (sscanf(s, sge_u32, &jobid) != 1) {
        sprintf(lasterror, MSG_GDI_STRINGISINVALID_SS, s, "JOB_ID");
        DRETURN(NULL);
    }

    if ((s=getenv(env_var_name)) != NULL) {
        if (strcmp(s, "undefined") == 0) {
            jataskid = 1;
        } else {
            if (sscanf(s, sge_u32, &jataskid) != 1) {
                sprintf(lasterror, MSG_GDI_STRINGISINVALID_SS, s, env_var_name);
                DRETURN(NULL);
            }
        }
    } else {
        sprintf(lasterror, MSG_GDI_MISSINGINENVIRONMENT_S, env_var_name);
        DRETURN(NULL);
    }

    /* ---- build up pe task request structure (see gdilib/sge_petaskL.h) */
    petrep = lCreateElem(PETR_Type);

    lSetUlong(petrep, PETR_jobid, jobid);
    lSetUlong(petrep, PETR_jataskid, jataskid);
    lSetString(petrep, PETR_owner, myname);
    lSetUlong(petrep, PETR_submission_time, sge_get_gmt());

    if (cwd != NULL) {
        lSetString(petrep, PETR_cwd, cwd);
    }

    if (environment != NULL) {
        lSetList(petrep, PETR_environment, lCopyList("environment", environment));
    }

    if (path_aliases != NULL) {
        lSetList(petrep, PETR_path_aliases, lCopyList("path_aliases", path_aliases));
    }


    if (queuename != NULL) {
        lSetString(petrep, PETR_queuename, queuename);
    }

    if (init_packbuffer(&pb, 1024, 0) != PACK_SUCCESS) {
        lFreeElem(&petrep);
        sprintf(lasterror, SFNMAX, MSG_GDI_OUTOFMEMORY);
        DRETURN(NULL);
    }

    pack_job_delivery(&pb, petrep);

    ret = gdi2_send_message_pb(ctx, 1, prognames[EXECD], 1, hostname,
                               TAG_JOB_EXECUTION, &pb, &dummymid);

    clear_packbuffer(&pb);

    lFreeElem(&petrep);

    if (ret != CL_RETVAL_OK) {
        sprintf(lasterror, MSG_GDI_SENDTASKTOEXECDFAILED_SS, hostname, cl_get_error_text(ret));
        DRETURN(NULL);
    }

    /* add list into our remote task list */
    rt = lAddElemStr(&remote_task_list, RT_tid, "none", RT_Type);
    lSetHost(rt, RT_hostname, hostname);
    lSetUlong(rt, RT_state, RT_STATE_WAIT4ACK);

    rcv_from_execd(ctx, OPT_SYNCHRON, TAG_JOB_EXECUTION);

    tid = (sge_tid_t) lGetString(rt, RT_tid);

    if (strcmp(tid, "none") == 0) {
        tid = NULL;
        sprintf(lasterror, MSG_GDI_EXECDONHOSTDIDNTACCEPTTASK_S, hostname);
    }

    /* now close message to execd */
    cl_commlib_shutdown_handle(cl_com_get_handle("execd_handle", 0), false);

    DRETURN(tid);
}
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);
         }
      }
Beispiel #6
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 #7
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;
}
static lListElem * 
qinstance_create(sge_gdi_ctx_class_t *ctx,
                 const lListElem *cqueue, lList **answer_list,
                 const char *hostname, bool *is_ambiguous, monitoring_t *monitor) 
{
   dstring buffer = DSTRING_INIT;
   const char *cqueue_name = lGetString(cqueue, CQ_name);
   lList *centry_list = *(object_type_get_master_list(SGE_TYPE_CENTRY));
   lListElem *ret = NULL;
   int index;

   DENTER(TOP_LAYER, "qinstance_create");
   
   ret = lCreateElem(QU_Type);

   /*
    * Pre-initialize some fields: hostname, full_name
    */
   lSetHost(ret, QU_qhostname, hostname);
   lSetString(ret, QU_qname, cqueue_name);
   sge_dstring_sprintf(&buffer, "%s@%s", cqueue_name, hostname);
   lSetString(ret, QU_full_name, sge_dstring_get_string(&buffer));
   sge_dstring_free(&buffer);

   /*
    * Initialize configuration attributes from CQ
    */
   *is_ambiguous = false;
   index = 0;
   while (cqueue_attribute_array[index].cqueue_attr != NoName) {
      bool tmp_is_ambiguous = false;
      bool tmp_has_changed_conf_attr = false;
      bool tmp_has_changed_state_attr = false;
      const char *matching_host_or_group = NULL;
      const char *matching_group = NULL;

      qinstance_modify_attribute(ctx,
                       ret, answer_list, cqueue, 
                       cqueue_attribute_array[index].qinstance_attr,
                       cqueue_attribute_array[index].cqueue_attr, 
                       cqueue_attribute_array[index].href_attr,
                       cqueue_attribute_array[index].value_attr,
                       cqueue_attribute_array[index].primary_key_attr,
                       &matching_host_or_group,
                       &matching_group,
                       &tmp_is_ambiguous, 
                       &tmp_has_changed_conf_attr,
                       &tmp_has_changed_state_attr,
                       true, NULL, monitor);

      *is_ambiguous |= tmp_is_ambiguous;

      index++;
   }

   qinstance_set_conf_slots_used(ret);
   qinstance_debit_consumable(ret, NULL, centry_list, 0, true);

   /*
    * Change qinstance state
    */
   sge_qmaster_qinstance_state_set_ambiguous(ret, *is_ambiguous);
   if (*is_ambiguous) {
      DPRINTF(("Qinstance "SFN"@"SFN" has ambiguous configuration\n",
               cqueue_name, hostname));
   } else {
      DPRINTF(("Qinstance "SFN"@"SFN" has non-ambiguous configuration\n",
               cqueue_name, hostname));
   }

   /*
    * For new qinstances we have to set some internal fields which
    * will be spooled later on:
    *    - state (modification according to initial state)
    *    - qversion
    */
   sge_qmaster_qinstance_state_set_unknown(ret, true);
   qinstance_check_unknown_state(ret, *object_type_get_master_list(SGE_TYPE_EXECHOST));
   sge_qmaster_qinstance_set_initial_state(ret);
   qinstance_initialize_sos_attr(ctx, ret, monitor);

   qinstance_increase_qversion(ret);

   DRETURN(ret);
}
/****** 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);
}
void *
sge_event_master_main(void *arg)
{
   bool do_endlessly = true;
   cl_thread_settings_t *thread_config = (cl_thread_settings_t*)arg;
   sge_gdi_ctx_class_t *ctx = NULL;
   monitoring_t monitor;
   monitoring_t *monitorp = &monitor;

   lListElem *report = NULL;
   lList *report_list = NULL;
   time_t next_prof_output = 0;

   DENTER(TOP_LAYER, "sge_event_master_main");

   DPRINTF(("started"));
   cl_thread_func_startup(thread_config);
   sge_monitor_init(&monitor, thread_config->thread_name, EDT_EXT, EMT_WARNING, EMT_ERROR);
   sge_qmaster_thread_init(&ctx, QMASTER, DELIVERER_THREAD, true);

   /* register at profiling module */
   set_thread_name(pthread_self(), "Deliver Thread");
   conf_update_thread_profiling("Deliver Thread");

   report_list = lCreateListHash("report list", REP_Type, false);
   report = lCreateElem(REP_Type);
   lSetUlong(report, REP_type, NUM_REP_REPORT_EVENTS);
   lSetHost(report, REP_host, ctx->get_qualified_hostname(ctx));
   lAppendElem(report_list, report);
 
   while (do_endlessly) {
      int execute = 0;

      thread_start_stop_profiling();

      /*
       * did a new event arrive which has a flush time of 0 seconds?
       */
      MONITOR_IDLE_TIME(sge_event_master_wait_next(), (&monitor), mconf_get_monitor_time(), 
                        mconf_is_monitor_message());

      MONITOR_MESSAGES((monitorp));
      MONITOR_EDT_COUNT((&monitor));
      MONITOR_CLIENT_COUNT((&monitor), lGetNumberOfElem(Event_Master_Control.clients));

      sge_event_master_process_requests(&monitor);
      sge_event_master_send_events(ctx, report, report_list, &monitor);
      sge_monitor_output(&monitor);

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

      /* pthread cancelation point */
      pthread_cleanup_push((void (*)(void *))sge_event_master_cleanup_monitor,
                           (void *)&monitor);
      pthread_cleanup_push((void (*)(void *))sge_event_master_cleanup_report_list,
                           (void *)&report_list);
      cl_thread_func_testcancel(thread_config);
      pthread_cleanup_pop(execute); 
      pthread_cleanup_pop(execute); 
      if (sge_thread_has_shutdown_started()) {
         DPRINTF(("waiting for termination\n"));
         sleep(1);
      }
   }

   /*
    * Don't add cleanup code here. It will never be executed. Instead register
    * a cleanup function with pthread_cleanup_push()/pthread_cleanup_pop() before 
    * and after the call of cl_thread_func_testcancel()
    */

   DRETURN(NULL);
}
/****** sge_advance_reservation/ar_validate() **********************************
*  NAME
*     ar_validate() -- validate a advance reservation
*
*  SYNOPSIS
*     bool ar_validate(lListElem *ar, lList **alpp, bool in_master)
*
*  FUNCTION
*     Ensures a new ar has valid start and end times
*
*  INPUTS
*     lListElem *ar   - the ar to check
*     lList **alpp    - answer list pointer
*     bool in_master  - are we in qmaster?
*     bool is_spool   - do we validate for spooling? 
*
*  RESULT
*     bool - true if OK, else false
*
*  NOTES
*     MT-NOTE: ar_validate() is MT safe
*******************************************************************************/
bool ar_validate(lListElem *ar, lList **alpp, bool in_master, bool is_spool)
{
   u_long32 start_time;
   u_long32 end_time;
   u_long32 duration;
   u_long32 now = sge_get_gmt();
   object_description *object_base = object_type_get_object_description();
   
   DENTER(TOP_LAYER, "ar_validate");

   /*   AR_start_time, SGE_ULONG        */
   if ((start_time = lGetUlong(ar, AR_start_time)) == 0) {
      start_time = now;
      lSetUlong(ar, AR_start_time, start_time);
   }

   /*   AR_end_time, SGE_ULONG        */
   end_time = lGetUlong(ar, AR_end_time);
   duration = lGetUlong(ar, AR_duration);
   
   if (end_time == 0 && duration == 0) {
      answer_list_add_sprintf(alpp, STATUS_EEXIST, ANSWER_QUALITY_ERROR,
                              MSG_AR_MISSING_VALUE_S, "end time or duration");
      goto ERROR;
   } else if (end_time == 0) {
      end_time = duration_add_offset(start_time, duration);
      duration = end_time  - start_time;
      lSetUlong(ar, AR_end_time, end_time);
      lSetUlong(ar, AR_duration, duration);
   } else if (duration == 0) {
      duration = end_time - start_time;
      lSetUlong(ar, AR_duration, duration);
   }

   if ((end_time - start_time) != duration) {
      answer_list_add_sprintf(alpp, STATUS_EEXIST, ANSWER_QUALITY_ERROR,
                              MSG_AR_START_END_DURATION_INVALID);
      goto ERROR;
   }

   if (start_time > end_time) {
      answer_list_add_sprintf(alpp, STATUS_EEXIST, ANSWER_QUALITY_ERROR,
                              MSG_AR_START_LATER_THAN_END);
      goto ERROR;
   }
   
   if (!is_spool) {
      if (start_time < now) {
         answer_list_add_sprintf(alpp, STATUS_EEXIST, ANSWER_QUALITY_ERROR,
                                 MSG_AR_START_IN_PAST);
         goto ERROR;
      }
   }
   /*   AR_owner, SGE_STRING */
   
   if (in_master) {
      /*    AR_name, SGE_STRING */
      NULL_OUT_NONE(ar, AR_name);
      if (object_verify_name(ar, alpp, AR_name, SGE_OBJ_AR)) {
         goto ERROR;
      }
      /*   AR_account, SGE_STRING */
      NULL_OUT_NONE(ar, AR_account);
      if (!lGetString(ar, AR_account)) {
         lSetString(ar, AR_account, DEFAULT_ACCOUNT);
      } else {
         if (verify_str_key(alpp, lGetString(ar, AR_account), MAX_VERIFY_STRING,
         "account string", QSUB_TABLE) != STATUS_OK) {
            goto ERROR;
         }
      }
      /*   AR_verify, SGE_ULONG              just verify the reservation or final case */
      /*   AR_error_handling, SGE_ULONG      how to deal with soft and hard exceptions */
      /*   AR_checkpoint_name, SGE_STRING    Named checkpoint */
      NULL_OUT_NONE(ar, AR_checkpoint_name);
      {
         /* request for non existing ckpt object will be refused */
         const char *ckpt_name = NULL;

         ckpt_name = lGetString(ar, AR_checkpoint_name);
         if (ckpt_name != NULL) {
            lList *master_ckpt_list = *object_base[SGE_TYPE_CKPT].list;
            lListElem *ckpt_ep = ckpt_list_locate(master_ckpt_list, ckpt_name);
            if (!ckpt_ep) {
               ERROR((SGE_EVENT, MSG_JOB_CKPTUNKNOWN_S, ckpt_name));
               answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
               goto ERROR;
            }
          }
      }
      /*   AR_resource_list, SGE_LIST */
      {
         lList *master_centry_list = *object_base[SGE_TYPE_CENTRY].list;

         if (centry_list_fill_request(lGetList(ar, AR_resource_list),
                                      alpp, master_centry_list, false, true,
                                      false)) {
            goto ERROR;
         }
         if (compress_ressources(alpp, lGetList(ar, AR_resource_list), SGE_OBJ_AR)) {
            goto ERROR;
         }
         
         if (!centry_list_is_correct(lGetList(ar, AR_resource_list), alpp)) {
            goto ERROR;
         }
      }
      /*   AR_queue_list, SGE_LIST */
      if (!qref_list_is_valid(lGetList(ar, AR_queue_list), alpp)) {
         goto ERROR;
      }
      /*   AR_mail_options, SGE_ULONG   */
      /*   AR_mail_list, SGE_LIST */
      
      /*   AR_master_queue_list  -masterq wc_queue_list, SGE_LIST bind master task to queue(s) */
      if (!qref_list_is_valid(lGetList(ar, AR_master_queue_list), alpp)) {
         goto ERROR;
      }
       
      
      /*   AR_pe, SGE_STRING,  AR_pe_range, SGE_LIST */
      NULL_OUT_NONE(ar, AR_pe);
      {
         const char *pe_name = NULL;
         lList *pe_range = NULL;
         
         pe_name = lGetString(ar, AR_pe);
         if (pe_name) {
            const lListElem *pep;
            pep = pe_list_find_matching(*object_base[SGE_TYPE_PE].list, pe_name);
            if (!pep) {
               ERROR((SGE_EVENT, MSG_JOB_PEUNKNOWN_S, pe_name));
               answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR);
               goto ERROR;
            }
            /* check pe_range */
            pe_range = lGetList(ar, AR_pe_range);
            if (object_verify_pe_range(alpp, pe_name, pe_range, SGE_OBJ_AR)!=STATUS_OK) {
               goto ERROR;
            }
         }
      }

      /*   AR_acl_list, SGE_LIST */
      if (userset_list_validate_access(lGetList(ar, AR_acl_list), ARA_name, alpp) != STATUS_OK) {
         goto ERROR;
      }
      
      /*   AR_xacl_list, SGE_LIST */
      if (userset_list_validate_access(lGetList(ar, AR_xacl_list), ARA_name, alpp) != STATUS_OK) {
         goto ERROR;
      }

      if (is_spool) {
         lListElem *jg;
         dstring cqueue_buffer = DSTRING_INIT;
         dstring hostname_buffer = DSTRING_INIT;
         for_each(jg, lGetList(ar, AR_granted_slots)){
            const char *hostname = NULL;
            const char *qname = lGetString(jg, JG_qname);
            bool has_hostname = false;
            bool has_domain = false;

            cqueue_name_split(qname, &cqueue_buffer, &hostname_buffer,
                              &has_hostname, &has_domain);
            hostname = sge_dstring_get_string(&hostname_buffer);
            lSetHost(jg, JG_qhostname, hostname);
         }
         sge_dstring_free(&cqueue_buffer);
         sge_dstring_free(&hostname_buffer);
      }
      /*   AR_type,  SGE_ULONG     */
      /*   AR_state, SGE_ULONG               state of the AR */
      if(lGetUlong(ar, AR_state) == ARL_UNKNOWN){
         lSetUlong(ar, AR_state, ARL_CREATION);  
      }
   }
   DRETURN(true);

ERROR:
   DRETURN(false);
}