/* ---------------------------------------- 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)); }
/****** 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); } }
/*-------------------------------------------------------------------------*/ 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; }
/*-------------------------------------------------------------------------*/ 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); }