/********************************************************************** This is the function used by the scheduler to get a complete list of complexes for a given queue. All templates are filled by actual values. With this list the scheduler can decide whether a request matches this queue. **********************************************************************/ int queue_complexes2scheduler(lList **new_centry_list, lListElem *queue, const lList *exechost_list, const lList *centry_list) { DENTER(BASIS_LAYER, "queue_complexes2scheduler"); lFreeList(new_centry_list); *new_centry_list = get_attribute_list(host_list_locate(exechost_list, "global"), queue ? host_list_locate(exechost_list, lGetHost(queue, QU_qhostname)) : NULL, queue, centry_list); DRETURN(0); }
/****** qmaster/setup_qmaster/sge_setup_job_resend() *************************** * NAME * sge_setup_job_resend() -- Setup job resend events. * * SYNOPSIS * void sge_setup_job_resend(void) * * FUNCTION * Register a job resend event for each job or array task which does have a * 'JTRANSFERING' status. * * INPUTS * void - none * * RESULT * void - none * * NOTES * MT-NOTE: sge_setup_job_resend() is not MT safe * *******************************************************************************/ void sge_setup_job_resend(void) { lListElem *job = NULL; object_description *object_base = object_type_get_object_description(); DENTER(TOP_LAYER, "sge_setup_job_resend"); job = lFirst(*object_base[SGE_TYPE_JOB].list); while (NULL != job) { lListElem *task; u_long32 job_num; job_num = lGetUlong(job, JB_job_number); task = lFirst(lGetList(job, JB_ja_tasks)); while (NULL != task) { if (lGetUlong(task, JAT_status) == JTRANSFERING) { lListElem *granted_queue, *qinstance, *host; const char *qname; u_long32 task_num, when; te_event_t ev; task_num = lGetUlong(task, JAT_task_number); granted_queue = lFirst(lGetList(task, JAT_granted_destin_identifier_list)); qname = lGetString(granted_queue, JG_qname); qinstance = cqueue_list_locate_qinstance(*object_base[SGE_TYPE_CQUEUE].list, qname); host = host_list_locate(*object_base[SGE_TYPE_EXECHOST].list, lGetHost(qinstance, QU_qhostname)); when = lGetUlong(task, JAT_start_time); when += MAX(load_report_interval(host), MAX_JOB_DELIVER_TIME); ev = te_new_event((time_t)when, TYPE_JOB_RESEND_EVENT, ONE_TIME_EVENT, job_num, task_num, "job-resend_event"); te_add_event(ev); te_free_event(&ev); DPRINTF(("Did add job resend for "sge_u32"/"sge_u32" at %d\n", job_num, task_num, when)); } task = lNext(task); } job = lNext(job); } DEXIT; return; } /* sge_setup_job_resend() */
/* provide a list of attributes containing all attributes for the given host */ int host_complexes2scheduler( lList **new_centry_list, lListElem *host, lList *exechost_list, lList *centry_list ) { DENTER(TOP_LAYER, "host_comlexes2scheduler"); if (!host) { DPRINTF(("!!missing host!!\n")); } /* build global complex and add it to result */ lFreeList(new_centry_list); *new_centry_list = get_attribute_list(host_list_locate(exechost_list, "global"), host, NULL, centry_list); DRETURN(0); }
/****** 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)); }
/****** qquota_output/qquota_output() ******************************************** * NAME * qquota_output() -- qquota output function * * SYNOPSIS * bool qquota_output(void *ctx, lList *host_list, lList *resource_match_list, * lList *user_list, lList *pe_list, lList *project_list, lList * *cqueue_list, lList **alpp, report_handler_t* report_handler) * * FUNCTION * print resource quota rule and the limit * * INPUTS * void *ctx - gdi handler * lList *host_list - selected hosts * lList *resource_match_list - selected resources * lList *user_list - selected users * lList *pe_list - selecte pes * lList *project_list - selected projects * lList *cqueue_list - selected cluster queues * lList **alpp - answer list * report_handler_t* report_handler - report handler for xml output * * RESULT * bool - true on success * false on error * * NOTES * MT-NOTE: qquota_output() is MT safe * *******************************************************************************/ bool qquota_output(sge_gdi_ctx_class_t *ctx, lList *host_list, lList *resource_match_list, lList *user_list, lList *pe_list, lList *project_list, lList *cqueue_list, lList **alpp, report_handler_t* report_handler) { lList *rqs_list = NULL; lList *centry_list = NULL; lList *userset_list = NULL; lList *hgroup_list = NULL; lList *exechost_list = NULL; lListElem* global_host = NULL; lListElem* exec_host = NULL; lList* printed_rules = NULL; /* Hash list of already printed resource quota rules (possible with -u user1,user2,user3...) */ bool ret = true; int xml_ret = 0; qquota_filter_t qquota_filter = { "*", "*", "*", "*", "*" }; dstring rule_name = DSTRING_INIT; DENTER(TOP_LAYER, "qquota_output"); /* If no user is requested on command line we set the current user as default */ qquota_filter.user = ctx->get_username(ctx); ret = get_all_lists(ctx, &rqs_list, ¢ry_list, &userset_list, &hgroup_list, &exechost_list, host_list, alpp); if (ret == true) { lListElem *rqs = NULL; printed_rules = lCreateList("rule_hash", ST_Type); global_host = host_list_locate(exechost_list, SGE_GLOBAL_NAME); if (report_handler != NULL) { xml_ret = report_handler->report_started(report_handler, alpp); if (xml_ret != QQUOTA_SUCCESS) { ret = false; goto qquota_output_error; } } for_each(rqs, rqs_list) { lListElem *rule = NULL; int rule_count = 1; if (lGetBool(rqs, RQS_enabled) == false) { continue; } for_each(rule, lGetList(rqs, RQS_rule)) { lListElem *user_ep = lFirst(user_list); lListElem *project_ep = lFirst(project_list); lListElem *pe_ep = lFirst(pe_list); lListElem *queue_ep = lFirst(cqueue_list); lListElem *host_ep = lFirst(host_list); do { if (user_ep != NULL) { qquota_filter.user = lGetString(user_ep, ST_name); } do { if (project_ep != NULL) { qquota_filter.project = lGetString(project_ep, ST_name); } do { if (pe_ep != NULL) { qquota_filter.pe = lGetString(pe_ep, ST_name); } do { if (queue_ep != NULL) { qquota_filter.queue = lGetString(queue_ep, ST_name); } do { if (host_ep != NULL) { qquota_filter.host = lGetString(host_ep, ST_name); } if (rqs_is_matching_rule(rule, qquota_filter.user, NULL, qquota_filter.project, qquota_filter.pe, qquota_filter.host, qquota_filter.queue, userset_list, hgroup_list)) { lListElem *limit = NULL; for_each(limit, lGetList(rule, RQR_limit)) { const char *limit_name = lGetString(limit, RQRL_name); lList *rue_list = lGetList(limit, RQRL_usage); lListElem *raw_centry = centry_list_locate(centry_list, limit_name); lListElem *rue_elem = NULL; if (raw_centry == NULL) { /* undefined centries can be ignored */ DPRINTF(("centry %s not defined -> IGNORING\n", limit_name)); continue; } if ((resource_match_list != NULL) && ((centry_list_locate(resource_match_list, limit_name) == NULL) && (centry_list_locate(resource_match_list, lGetString(raw_centry, CE_shortcut)) == NULL))) { DPRINTF(("centry %s was not requested on CLI -> IGNORING\n", limit_name)); continue; } if (lGetString(rule, RQR_name)) { sge_dstring_sprintf(&rule_name, "%s/%s", lGetString(rqs, RQS_name), lGetString(rule, RQR_name)); } else { sge_dstring_sprintf(&rule_name, "%s/%d", lGetString(rqs, RQS_name), rule_count); } if (lGetUlong(raw_centry, CE_consumable)) { /* for consumables we need to walk through the utilization and search for matching values */ DPRINTF(("found centry %s - consumable\n", limit_name)); for_each(rue_elem, rue_list) { u_long32 dominant = 0; const char *rue_name = lGetString(rue_elem, RUE_name); char *cp = NULL; stringT user, project, pe, queue, host; dstring limit_str = DSTRING_INIT; dstring value_str = DSTRING_INIT; qquota_filter_t qf = { NULL, NULL, NULL, NULL, NULL }; /* check user name */ cp = qquota_get_next_filter(user, rue_name); /* usergroups have the same beginning character @ as host groups */ if (is_hgroup_name(qquota_filter.user)) { lListElem *ugroup = NULL; if ((ugroup = userset_list_locate(userset_list, &qquota_filter.user[1])) != NULL) { if (sge_contained_in_access_list(user, NULL, ugroup, NULL) == 0) { continue; } } } else { if ((strcmp(user, "-") != 0) && (strcmp(qquota_filter.user, "*") != 0) && (fnmatch(qquota_filter.user, user, 0) != 0)) { continue; } } /* check project */ cp = qquota_get_next_filter(project, cp); if ((strcmp(project, "-") != 0) && (strcmp(qquota_filter.project, "*") != 0) && (fnmatch(qquota_filter.project, project, 0) != 0)) { continue; } /* check parallel environment */ cp = qquota_get_next_filter(pe, cp); if ((strcmp(pe, "-") != 0) && (strcmp(qquota_filter.pe, "*") != 0) && (fnmatch(qquota_filter.pe, pe, 0) != 0) ) { continue; } /* check cluster queue */ cp = qquota_get_next_filter(queue, cp); if ((strcmp(queue, "-") != 0) && (strcmp(qquota_filter.queue, "*") != 0) && (fnmatch(qquota_filter.queue, queue, 0) != 0)) { continue; } /* check host name */ cp = qquota_get_next_filter(host, cp); if (is_hgroup_name(qquota_filter.host)) { lListElem *hgroup = NULL; if ((hgroup = hgroup_list_locate(hgroup_list, qquota_filter.host)) != NULL) { lList *host_list = NULL; hgroup_find_all_references(hgroup, NULL, hgroup_list, &host_list, NULL); if (host_list == NULL && lGetElemHost(host_list, HR_name, host) == NULL) { lFreeList(&host_list); continue; } lFreeList(&host_list); } } else { if ((strcmp(host, "-") != 0) && (strcmp(qquota_filter.host, "*") != 0) && (fnmatch(qquota_filter.host, host, 0) != 0) ) { continue; } } if (lGetBool(limit, RQRL_dynamic)) { exec_host = host_list_locate(exechost_list, host); sge_dstring_sprintf(&limit_str, "%d", (int)scaled_mixed_load(lGetString(limit, RQRL_value), global_host, exec_host, centry_list)); } else { lSetDouble(raw_centry, CE_pj_doubleval, lGetDouble(limit, RQRL_dvalue)); sge_get_dominant_stringval(raw_centry, &dominant, &limit_str); } lSetDouble(raw_centry,CE_pj_doubleval, lGetDouble(rue_elem, RUE_utilized_now)); sge_get_dominant_stringval(raw_centry, &dominant, &value_str); qf.user = user; qf.project = project; qf.pe = pe; qf.queue = queue; qf.host = host; ret = qquota_print_out_rule(rule, rule_name, limit_name, sge_dstring_get_string(&value_str), sge_dstring_get_string(&limit_str), qf, raw_centry, report_handler, printed_rules, alpp); sge_dstring_free(&limit_str); sge_dstring_free(&value_str); } } else { /* static values */ qquota_filter_t qf = { NULL, NULL, NULL, NULL, NULL }; DPRINTF(("found centry %s - static value\n", limit_name)); ret = qquota_print_out_rule(rule, rule_name, limit_name, NULL, lGetString(limit, RQRL_value), qf, raw_centry, report_handler, printed_rules, alpp); } } } } while ((host_ep = lNext(host_ep))); } while ((queue_ep = lNext(queue_ep))); } while ((pe_ep = lNext(pe_ep))); } while ((project_ep = lNext(project_ep)));