/****** 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)));
static int check_config(lList **alpp, lListElem *conf) { lListElem *ep; const char *name, *value; const char *conf_name; DENTER(TOP_LAYER, "check_config"); conf_name = lGetHost(conf, CONF_name); for_each(ep, lGetList(conf, CONF_entries)) { name = lGetString(ep, CF_name); value = lGetString(ep, CF_value); if (name == NULL) { ERROR((SGE_EVENT, MSG_CONF_NAMEISNULLINCONFIGURATIONLISTOFX_S, conf_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } if (value == NULL) { ERROR((SGE_EVENT, MSG_CONF_VALUEISNULLFORATTRXINCONFIGURATIONLISTOFY_SS, name, conf_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } if (!strcmp(name, "loglevel")) { u_long32 tmp_uval; if (sge_parse_loglevel_val(&tmp_uval, value) != 1) { ERROR((SGE_EVENT, MSG_CONF_GOTINVALIDVALUEXFORLOGLEVEL_S, value)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } else if (strcmp(name, "jsv_url") == 0) { if (strcasecmp("none", value) != 0) { dstring input = DSTRING_INIT; dstring type = DSTRING_INIT; dstring user = DSTRING_INIT; dstring path = DSTRING_INIT; bool lret = true; sge_dstring_append(&input, value); lret = jsv_url_parse(&input, alpp, &type, &user, &path, false); sge_dstring_free(&input); sge_dstring_free(&type); sge_dstring_free(&user); sge_dstring_free(&path); if (!lret) { /* answer is written by jsv_url_parse */ DRETURN(STATUS_EEXIST); } } } else if (!strcmp(name, "shell_start_mode")) { if ((strcasecmp("unix_behavior", value) != 0) && (strcasecmp("posix_compliant", value) != 0) && (strcasecmp("script_from_stdin", value) != 0) ) { ERROR((SGE_EVENT, MSG_CONF_GOTINVALIDVALUEXFORSHELLSTARTMODE_S, value)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } else if (!strcmp(name, "shell")) { if (!path_verify(name, alpp, "shell", true)) { ERROR((SGE_EVENT, MSG_CONF_GOTINVALIDVALUEXFORSHELL_S, value)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } else if (!strcmp(name, "load_report_time")) { /* do not allow infinity entry for load_report_time */ if (strcasecmp(value, "infinity") == 0) { ERROR((SGE_EVENT, MSG_CONF_INFNOTALLOWEDFORATTRXINCONFLISTOFY_SS, name, conf_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } else if (!strcmp(name, "max_unheard")) { /* do not allow infinity entry */ if (strcasecmp(value,"infinity") == 0) { ERROR((SGE_EVENT, MSG_CONF_INFNOTALLOWEDFORATTRXINCONFLISTOFY_SS, name, conf_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } else if (!strcmp(name, "admin_user")) { struct passwd pw_struct; char *buffer; int size; size = get_pw_buffer_size(); buffer = sge_malloc(size); if (strcasecmp(value, "none") && !sge_getpwnam_r(value, &pw_struct, buffer, size)) { ERROR((SGE_EVENT, MSG_CONF_GOTINVALIDVALUEXASADMINUSER_S, value)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); sge_free(&buffer); DRETURN(STATUS_EEXIST); } sge_free(&buffer); } else if (!strcmp(name, "user_lists")||!strcmp(name, "xuser_lists")) { lList *tmp = NULL; int ok; /* parse just for .. */ if (lString2ListNone(value, &tmp, US_Type, US_name, " \t,")) { ERROR((SGE_EVENT, MSG_CONF_FORMATERRORFORXINYCONFIG_SS, name, conf_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } /* .. checking userset names */ ok = (userset_list_validate_acl_list(tmp, alpp) == STATUS_OK); lFreeList(&tmp); if (!ok) { DRETURN(STATUS_EEXIST); } } else if (!strcmp(name, "projects") || !strcmp(name, "xprojects")) { lList *tmp = NULL; int ok=1; /* parse just for .. */ if (lString2ListNone(value, &tmp, PR_Type, PR_name, " \t,")) { ERROR((SGE_EVENT, MSG_CONF_FORMATERRORFORXINYCONFIG_SS, name, conf_name)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } /* .. checking project names */ ok = (verify_project_list(alpp, tmp, *object_type_get_master_list(SGE_TYPE_PROJECT), name, "configuration", conf_name)==STATUS_OK); lFreeList(&tmp); if (!ok) { DRETURN(STATUS_EEXIST); } } else if (!strcmp(name, "prolog") || !strcmp(name, "epilog") || !strcmp(name, "mailer")) { if (strcasecmp(value, "none")) { const char *t, *script = value; /* skip user name */ if ((t = strpbrk(script, "@ ")) && *t == '@') script = &t[1]; /* force use of absolute paths if string <> none */ if (script[0] != '/' ) { ERROR((SGE_EVENT, MSG_CONF_THEPATHGIVENFORXMUSTSTARTWITHANY_S, name)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } /* ensure that variables are valid */ if (replace_params(script, NULL, 0, prolog_epilog_variables)) { ERROR((SGE_EVENT, MSG_CONF_PARAMETERXINCONFIGURATION_SS, name, err_msg)); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } } else if (!strcmp(name, "auto_user_oticket") || !strcmp(name, "auto_user_fshare")) { u_long32 uval = 0; if (!extended_parse_ulong_val(NULL, &uval, TYPE_INT, value, NULL, 0, 0, true)) { ERROR((SGE_EVENT, MSG_CONF_FORMATERRORFORXINYCONFIG_SS, name, value ? value : "(NULL)")); answer_list_add(alpp, SGE_EVENT, STATUS_EEXIST, ANSWER_QUALITY_ERROR); DRETURN(STATUS_EEXIST); } } /* * check paths, see also CR 6506580. * The following must be none or a valid absolute path: * - load_sensor * - set_token_cmd * - pag_cmd * - shepherd_cmd * * The following must be a valid absolute path: * - mailer * - xterm * - *_daemon, may also be "builtin" */ else if (strcmp(name, "set_token_cmd") == 0 || strcmp(name, "pag_cmd") == 0 || strcmp(name, "shepherd_cmd") == 0) { if (strcasecmp(value, "none") != 0) { if (!path_verify(value, alpp, name, true)) { answer_list_log(alpp, false, false); DRETURN(STATUS_EEXIST); } } } else if (strcmp(name, "mailer") == 0 || strcmp(name, "xterm") == 0) { if (!path_verify(value, alpp, name, true)) { answer_list_log(alpp, false, false); DRETURN(STATUS_EEXIST); } } else if (strcmp(name, "qlogin_daemon") == 0 || strcmp(name, "rlogin_daemon") == 0 || strcmp(name, "rsh_daemon") == 0) { if (strcasecmp(value, "builtin") != 0) { if (!path_verify(value, alpp, name, true)) { answer_list_log(alpp, false, false); DRETURN(STATUS_EEXIST); } } } /* load_sensor is a comma separated list of scripts */ else if (strcmp(name, "load_sensor") == 0 && strcasecmp(value, "none") != 0) { struct saved_vars_s *context = NULL; const char *path = sge_strtok_r(value, ",", &context); do { if (!path_verify(path, alpp, name, true)) { answer_list_log(alpp, false, false); sge_free_saved_vars(context); DRETURN(STATUS_EEXIST); } } while ((path = sge_strtok_r(NULL, ",", &context)) != NULL); sge_free_saved_vars(context); } }
/****** cull/dump_scan/lUndumpList() ****************************************** * NAME * lUndumpList() -- Reads a by lDumpList dumped dump * * SYNOPSIS * lList* lUndumpList(FILE *fp, const char *name, const lDescr *dp) * * FUNCTION * Reads a by lDumpList dumped dump into the memory. * * INPUTS * FILE *fp - file pointer * const char *name - new name of list or NULL if the old name in the * dumpfile should be used as listname * const lDescr *dp - new list descriptor or NULL if the old list * descriptor should be used as list descriptor * * RESULT * lList* - Read list * * NOTES * Actually a type/name matching is only performed for the list * itself and not for its sublists. * If an implementation of changed sublist descriptors is desired * we can probably use the following syntax for lUndumpList. * lList* lUndumpList(fp, name, formatstring, ...) * with formatstring like "%T(%I -> %T(%I->%T))" and the varargs * list: ".....", lDescr1, fieldname1, lDescr2, fieldname2, lDescr3 * or write a wrapper around lUndumpList which parses this format and * hands over the varargs list to lUndumpList ******************************************************************************/ lList *lUndumpList(FILE *fp, const char *name, const lDescr *dp) { lList *lp = NULL; lListElem *fep, *ep; lDescr *fdp = NULL; int i, j, nelem, n, k; int *found; char *oldname; DENTER(CULL_LAYER, "lUndumpList"); if (!fp) { LERROR(LEFILENULL); DRETURN(NULL); } /* read bra */ if (fGetBra(fp)) { printf("bra is missing\n"); LERROR(LESYNTAX); DRETURN(NULL); } /* read listname */ if (fGetString(fp, &oldname)) { printf("fGetString failed\n"); LERROR(LEFIELDREAD); DRETURN(NULL); } /* read number of elems */ if (fGetInt(fp, &nelem)) { printf("fGetInt failed\n"); LERROR(LEFIELDREAD); DRETURN(NULL); } /* read Descriptor from file */ if (!(fdp = lUndumpDescr(fp))) { LERROR(LEFGETDESCR); DRETURN(NULL); } if (!dp) /* dp is NULL, use lDescr from dumpfile */ dp = fdp; /* use old name (from file) if name is NULL */ if (!(lp = lCreateList((name) ? name : oldname, dp))) { FREE(fdp); LERROR(LECREATELIST); DRETURN(NULL); } free(oldname); /* fGetString strdup's */ if ((n = lCountDescr(dp)) <= 0) { LERROR(LECOUNTDESCR); FREE(fdp); lFreeList(&lp); DRETURN(NULL); } if (!(found = (int *) malloc(sizeof(int) * n))) { LERROR(LEMALLOC); FREE(fdp); lFreeList(&lp); DRETURN(NULL); } /* Initialize found array */ for (i = 0; i < n; i++) found[i] = -1; /* Here warnings are displayed if there are additional or missing fields */ for (j = 0; fdp[j].nm != NoName; j++) { for (i = 0; i < n; i++) { if (dp[i].nm == fdp[j].nm && dp[i].mt == fdp[j].mt) { if (found[i] != -1) DPRINTF(("lUndumpList: field %s found twice\n", lNm2Str(dp[i].nm))); found[i] = j; break; } } if (i == n) DPRINTF(("lUndumpList: field %s not needed\n", lNm2Str(fdp[j].nm))); } for (i = 0; i < n; i++) if (found[i] == -1) DPRINTF(("lUndumpList: field %s not found\n", lNm2Str(dp[i].nm))); /* LOOP OVER THE LIST ELEMENTS */ for (k = 0; k < nelem; k++) { if (!(fep = lUndumpElemFp(fp, fdp))) { LERROR(LEUNDUMPELEM); lFreeList(&lp); FREE(found); FREE(fdp); DRETURN(NULL); } if (!(ep = lCreateElem(dp))) { lFreeList(&lp); FREE(found); FREE(fdp); LERROR(LECREATEELEM); DRETURN(NULL); } for (i = 0; i < n; i++) { if (found[i] == -1) { continue; } else if (lCopySwitchPack(fep, ep, found[i], i, true, NULL, NULL) == -1) { lFreeList(&lp); lFreeElem(&ep); FREE(found); FREE(fdp); LERROR(LECOPYSWITCH); DRETURN(NULL); } } lFreeElem(&fep); if (lAppendElem(lp, ep) == -1) { lFreeList(&lp); lFreeElem(&ep); FREE(found); FREE(fdp); LERROR(LEAPPENDELEM); DRETURN(NULL); } } /* read ket */ if (fGetKet(fp)) { lFreeList(&lp); printf("ket is missing\n"); LERROR(LESYNTAX); } FREE(found); FREE(fdp); DRETURN(lp); }
/************************************************************ sge_mod_sharetree - Master code Modify a share tree lListElem *ep, This is the new share tree lList **lpp, list to change ************************************************************/ int sge_mod_sharetree(sge_gdi_ctx_class_t *ctx, lListElem *ep, lList **lpp, lList **alpp, char *ruser, char *rhost ) { int ret; int prev_version; int adding; lList *found = NULL; object_description *object_base = object_type_get_object_description(); DENTER(TOP_LAYER, "sge_mod_sharetree"); /* do some checks */ if (!ep || !ruser || !rhost) { CRITICAL((SGE_EVENT, MSG_SGETEXT_NULLPTRPASSED_S, SGE_FUNC)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DEXIT; return STATUS_EUNKNOWN; } ret = check_sharetree(alpp, ep, *object_base[SGE_TYPE_USER].list, *object_base[SGE_TYPE_PROJECT].list, NULL, &found); lFreeList(&found); if (ret) { /* alpp gets filled by check_sharetree() */ DRETURN(STATUS_EUNKNOWN); } /* check for presence of sharetree list and create if neccesary */ if (!*lpp) { prev_version = 0; *lpp = lCreateList("sharetree list", STN_Type); adding = 1; } else if (lGetNumberOfElem(*lpp) == 0) { prev_version = 0; adding = 1; } else { lListElem *first = lFirst(*lpp); /* real action: change user or project We simply replace the old element with the new one. If there is no old we simle add the new. */ prev_version = lGetUlong(lFirst(*lpp), STN_version); lRemoveElem(*lpp, &first); adding = 0; } lSetUlong(ep, STN_version, prev_version+1); id_sharetree(alpp, ep, 0, NULL); /* now insert new element */ lAppendElem(*lpp, lCopyElem(ep)); /* write sharetree to file */ if (!sge_event_spool(ctx, alpp, 0, sgeE_NEW_SHARETREE, 0, 0, NULL, NULL, NULL, ep, NULL, NULL, true, true)) { /* answer list gets filled in sge_event_spool() */ DEXIT; return ret; } if (adding) { INFO((SGE_EVENT, MSG_STREE_ADDSTREE_SSII, ruser, rhost, lGetNumberOfNodes(ep, NULL, STN_children), lGetNumberOfLeafs(ep, NULL, STN_children))); } else { INFO((SGE_EVENT, MSG_STREE_MODSTREE_SSII, ruser, rhost, lGetNumberOfNodes(ep, NULL, STN_children), lGetNumberOfLeafs(ep, NULL, STN_children))); } answer_list_add(alpp, SGE_EVENT, STATUS_OK, ANSWER_QUALITY_INFO); DEXIT; return STATUS_OK; }
/****** test_category/test() *************************************************** * NAME * test() -- executes one test including a performance test run * * SYNOPSIS * int test(data_entry_t *test, char *result, int count) * * INPUTS * data_entry_t *test - one test setup * char *result - expected category * int count - test number * * RESULT * int - 0 okay, 1 failed * * NOTES * MT-NOTE: test() is MT safe * *******************************************************************************/ static int test(data_entry_t *test, char *result, int count) { int ret = 0; lListElem *job_elem = NULL; lList *access_list = NULL; lList *project_list = NULL; lList *rqs_list = NULL; printf("\ntest %d:\n-------\n", test->test_nr); job_elem = test_create_job(test, 1); if (test->is_access_list == 1) { access_list = test_create_access(); } if (test->project) { project_list = test_create_project(test->project); } if (test->rqs) { rqs_list = test_create_rqs(); } if (job_elem != NULL) { dstring category_str = DSTRING_INIT; sge_build_job_category_dstring(&category_str, job_elem, access_list, project_list, NULL, rqs_list); printf("got : <%s>\n", sge_dstring_get_string(&category_str)!=NULL?sge_dstring_get_string(&category_str):"<NULL>"); if (result != NULL && sge_dstring_get_string(&category_str) != NULL) { if (strcmp(result, sge_dstring_get_string(&category_str)) == 0) { } else { ret = 1; printf("expected: <%s>\n", result!=NULL? result:"<NULL>"); } } else if (result == NULL && sge_dstring_get_string(&category_str) == NULL) { } else { ret = 1; printf("expected: <%s>\n", result!=NULL? result:"<NULL>"); } if (ret == 0) { int i; int max = 10000; printf(" => category outputs match\n"); lFreeElem(&job_elem); for (i = 1; i <= 500; i*=6) { printf("test with %dx :", i); job_elem = test_create_job(test, i); if (job_elem != NULL) { double time = test_performance(job_elem, max, access_list, NULL, rqs_list); if (time > 1) { max /= 10; } lFreeElem(&job_elem); } else { printf("failed to create job\n"); ret = 1; break; } } } else { printf(" => test failed\n"); } sge_dstring_free(&category_str); } else { printf("failed to create job for test %d\n", count); ret = 1; } lFreeElem(&job_elem); lFreeList(&access_list); lFreeList(&project_list); lFreeList(&rqs_list); return ret; }
/****** 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; }
/*-------------------------------------------------------------------------*/ int main(int argc, char **argv) { int ret; int my_pid; int ret_val; int printed_points = 0; int max_enroll_tries; static char tmp_err_file_name[SGE_PATH_MAX]; time_t next_prof_output = 0; int execd_exit_state = 0; lList **master_job_list = NULL; sge_gdi_ctx_class_t *ctx = NULL; lList *alp = NULL; DENTER_MAIN(TOP_LAYER, "execd"); #if defined(LINUX) gen_procList (); #endif prof_mt_init(); set_thread_name(pthread_self(),"Execd Thread"); prof_set_level_name(SGE_PROF_CUSTOM1, "Execd Thread", NULL); prof_set_level_name(SGE_PROF_CUSTOM2, "Execd Dispatch", NULL); #ifdef __SGE_COMPILE_WITH_GETTEXT__ /* init language output for gettext() , it will use the right language */ sge_init_language_func((gettext_func_type) gettext, (setlocale_func_type) setlocale, (bindtextdomain_func_type) bindtextdomain, (textdomain_func_type) textdomain); sge_init_language(NULL,NULL); #endif /* __SGE_COMPILE_WITH_GETTEXT__ */ /* This needs a better solution */ umask(022); /* Initialize path for temporary logging until we chdir to spool */ my_pid = getpid(); sprintf(tmp_err_file_name,"%s."sge_U32CFormat"", TMP_ERR_FILE_EXECD, sge_u32c(my_pid)); log_state_set_log_file(tmp_err_file_name); /* exit func for SGE_EXIT() */ sge_sig_handler_in_main_loop = 0; sge_setup_sig_handlers(EXECD); if (sge_setup2(&ctx, EXECD, MAIN_THREAD, &alp, false) != AE_OK) { answer_list_output(&alp); SGE_EXIT((void**)&ctx, 1); } ctx->set_exit_func(ctx, execd_exit_func); #if defined(SOLARIS) /* Init shared SMF libs if necessary */ if (sge_smf_used() == 1 && sge_smf_init_libs() != 0) { SGE_EXIT((void**)&ctx, 1); } #endif /* prepare daemonize */ if (!getenv("SGE_ND")) { sge_daemonize_prepare(ctx); } if ((ret=sge_occupy_first_three())>=0) { CRITICAL((SGE_EVENT, MSG_FILE_REDIRECTFD_I, ret)); SGE_EXIT((void**)&ctx, 1); } lInit(nmv); /* unset XAUTHORITY if set */ if (getenv("XAUTHORITY") != NULL) { sge_unsetenv("XAUTHORITY"); } parse_cmdline_execd(argv); /* exit if we can't get communication handle (bind port) */ max_enroll_tries = 30; while (cl_com_get_handle(prognames[EXECD],1) == NULL) { ctx->prepare_enroll(ctx); max_enroll_tries--; if (max_enroll_tries <= 0 || shut_me_down) { /* exit after 30 seconds */ if (printed_points != 0) { printf("\n"); } CRITICAL((SGE_EVENT, MSG_COM_ERROR)); SGE_EXIT((void**)&ctx, 1); } if (cl_com_get_handle(prognames[EXECD],1) == NULL) { /* sleep when prepare_enroll() failed */ sleep(1); if (max_enroll_tries < 27) { printf("."); printed_points++; fflush(stdout); } } } if (printed_points != 0) { printf("\n"); } /* * now the commlib up and running. Set execd application status function * ( commlib callback function for qping status information response * messages (SIRM) ) */ ret_val = cl_com_set_status_func(sge_execd_application_status); if (ret_val != CL_RETVAL_OK) { ERROR((SGE_EVENT, cl_get_error_text(ret_val)) ); } /* test connection */ { cl_com_SIRM_t* status = NULL; ret_val = cl_commlib_get_endpoint_status(ctx->get_com_handle(ctx), (char *)ctx->get_master(ctx, true), (char*)prognames[QMASTER], 1, &status); if (ret_val != CL_RETVAL_OK) { ERROR((SGE_EVENT, cl_get_error_text(ret_val))); ERROR((SGE_EVENT, MSG_CONF_NOCONFBG)); } cl_com_free_sirm_message(&status); } /* finalize daeamonize */ if (!getenv("SGE_ND")) { sge_daemonize_finalize(ctx); } /* daemonizes if qmaster is unreachable */ sge_setup_sge_execd(ctx, tmp_err_file_name); /* are we using qidle or not */ sge_ls_qidle(mconf_get_use_qidle()); sge_ls_gnu_ls(1); DPRINTF(("use_qidle: %d\n", mconf_get_use_qidle())); /* test load sensor (internal or external) */ { lList *report_list = sge_build_load_report(ctx->get_qualified_hostname(ctx), ctx->get_binary_path(ctx)); lFreeList(&report_list); } /* here we have to wait for qmaster registration */ while (sge_execd_register_at_qmaster(ctx, false) != 0) { if (sge_get_com_error_flag(EXECD, SGE_COM_ACCESS_DENIED, true)) { /* This is no error */ DPRINTF(("***** got SGE_COM_ACCESS_DENIED from qmaster *****\n")); } if (sge_get_com_error_flag(EXECD, SGE_COM_ENDPOINT_NOT_UNIQUE, false)) { execd_exit_state = SGE_COM_ENDPOINT_NOT_UNIQUE; break; } if (shut_me_down != 0) { break; } sleep(30); } /* * Terminate on SIGTERM or hard communication error */ if (execd_exit_state != 0 || shut_me_down != 0) { sge_shutdown((void**)&ctx, execd_exit_state); DRETURN(execd_exit_state); } /* * We write pid file when we are connected to qmaster. Otherwise an old * execd might overwrite our pidfile. */ sge_write_pid(EXECD_PID_FILE); /* * At this point we are sure we are the only sge_execd and we are connected * to the current qmaster. First we have to report any reaped children * that might exist. */ starting_up(); /* * Log a warning message if execd hasn't been started by a superuser */ if (!sge_is_start_user_superuser()) { WARNING((SGE_EVENT, MSG_SWITCH_USER_NOT_ROOT)); } #ifdef COMPILE_DC if (ptf_init()) { CRITICAL((SGE_EVENT, MSG_EXECD_NOSTARTPTF)); SGE_EXIT((void**)&ctx, 1); } INFO((SGE_EVENT, MSG_EXECD_STARTPDCANDPTF)); #endif master_job_list = object_type_get_master_list(SGE_TYPE_JOB); *master_job_list = lCreateList("Master_Job_List", JB_Type); job_list_read_from_disk(master_job_list, "Master_Job_List", 0, SPOOL_WITHIN_EXECD, job_initialize_job); /* clean up jobs hanging around (look in active_dir) */ clean_up_old_jobs(ctx, 1); execd_trash_load_report(); sge_set_flush_lr_flag(true); sge_sig_handler_in_main_loop = 1; if (thread_prof_active_by_id(pthread_self())) { prof_start(SGE_PROF_CUSTOM1, NULL); prof_start(SGE_PROF_CUSTOM2, NULL); prof_start(SGE_PROF_GDI_REQUEST, NULL); } else { prof_stop(SGE_PROF_CUSTOM1, NULL); prof_stop(SGE_PROF_CUSTOM2, NULL); prof_stop(SGE_PROF_GDI_REQUEST, NULL); } PROF_START_MEASUREMENT(SGE_PROF_CUSTOM1); /* Start dispatching */ execd_exit_state = sge_execd_process_messages(ctx); /* * This code is only reached when dispatcher terminates and execd goes down. */ /* log if we received SIGPIPE signal */ if (sge_sig_handler_sigpipe_received) { sge_sig_handler_sigpipe_received = 0; INFO((SGE_EVENT, "SIGPIPE received\n")); } #if defined(LINUX) free_procList(); #endif lFreeList(master_job_list); PROF_STOP_MEASUREMENT(SGE_PROF_CUSTOM1); if (prof_is_active(SGE_PROF_ALL)) { time_t now = (time_t)sge_get_gmt(); if (now > next_prof_output) { prof_output_info(SGE_PROF_ALL, false, "profiling summary:\n"); prof_reset(SGE_PROF_ALL,NULL); next_prof_output = now + 60; } } sge_prof_cleanup(); sge_shutdown((void**)&ctx, execd_exit_state); DRETURN(execd_exit_state); }
/*-------------------------------------------------------------------------*/ static void qmonManopAdd(Widget w, XtPointer cld, XtPointer cad) { int type = dialog_mode; lList *lp = NULL; lList *alp = NULL; lEnumeration *what = NULL; String user = NULL; Widget username; int nm; lDescr *dp; DENTER(GUI_LAYER, "qmonManopAdd"); switch (type) { case SGE_UM_LIST: dp = UM_Type; nm = UM_name; username = manager_name; break; case SGE_UO_LIST: dp = UO_Type; nm = UO_name; username = operator_name; break; case SGE_UU_LIST: dp = UU_Type; nm = UU_name; username = user_name; break; case SGE_US_LIST: if ((long)cld == 1) qmonUsersetAdd(w, NULL, NULL); else qmonUsersetModify(w, NULL, NULL); DEXIT; return; default: DEXIT; return; } user = XmtInputFieldGetString(username); if (user && user[0] != '\0' && user[0] != ' ') { what = lWhat("%T(ALL)", dp); if (!(lp = lCreateElemList("AH", dp, 1))) { fprintf(stderr, "lCreateElemList failed\n"); lFreeWhat(&what); DEXIT; return; } lSetString(lFirst(lp), nm, user); /* if (type == SGE_UU_LIST) */ /* lSetString(lFirst(lp), UU_default_project, "NONE"); */ alp = qmonAddList(type, qmonMirrorListRef(type), nm, &lp, NULL, what); qmonMessageBox(w, alp, 0); updateManopList(); XmtInputFieldSetString(username, ""); lFreeWhat(&what); lFreeList(&lp); lFreeList(&alp); } DEXIT; }
/*-------------------------------------------------------------------------*/ static void qmonUsersetOk(Widget w, XtPointer cld, XtPointer cad) { String usetname = NULL; XmString xusetname = NULL; lList *lp = NULL; lList *ul = NULL; lList *alp = NULL; lListElem *up = NULL; lEnumeration *what = NULL; Boolean status = False; int usettype = 0; DENTER(GUI_LAYER, "qmonUsersetOk"); /* ** get the dialog data and */ usetname = XmtInputFieldGetString(uset_name); usettype = XmtChooserGetState(uset_type); /* ** usetname required, show warning dialog */ if (usetname && usetname[0] != '\0') { ul = XmStringToCull(uset_user_list, UE_Type, UE_name, ALL_ITEMS); /* ** do gdi stuff here */ if (add_mode) { lAddElemStr(&lp, US_name, usetname, US_Type); } else { up = lCopyElem(lGetElemStr(qmonMirrorList(SGE_US_LIST), US_name, usetname)); lp = lCreateList("userset", US_Type); lAppendElem(lp, up); } lSetList(lFirst(lp), US_entries, ul); lSetUlong(lFirst(lp), US_type, usettype); what = lWhat("%T(ALL)", US_Type); if (add_mode) { alp = qmonAddList(SGE_US_LIST, qmonMirrorListRef(SGE_US_LIST), US_name, &lp, NULL, what); } else { alp = qmonModList(SGE_US_LIST, qmonMirrorListRef(SGE_US_LIST), US_name, &lp, NULL, what); } if (!qmonMessageBox(w, alp, 0)) status = True; updateUsersetList(); xusetname = XmtCreateXmString(usetname); XmListSelectItem(userset_names, xusetname, True); XmStringFree(xusetname); lFreeWhat(&what); lFreeList(&lp); lFreeList(&alp); } else { qmonMessageShow(w, True, "Userset List Name required !"); } if (status) XtUnmanageChild(userset_ask_layout); DEXIT; }
/*-------------------------------------------------------------------------*/ void qmonRequestPopup(Widget w, XtPointer cld, XtPointer cad) { Widget request_hardsoft, parent, request_clear, request_okay, request_cancel; lList *hrl = NULL; lList *srl = NULL; lList *rll = NULL; lListElem *ep = NULL; lListElem *rp = NULL; lList *alp = NULL; DENTER(GUI_LAYER, "qmonRequestPopup"); parent = XmtGetShell(w); DPRINTF(("parent = %s\n", XtName(parent) )); if (!request_dialog) { request_dialog = XmtBuildQueryDialog(parent, "request_shell", NULL, 0, "request_rtype", &request_rtype, "request_rr", &request_rr, "request_hr", &request_hr, "request_sr", &request_sr, "request_hardsoft", &request_hardsoft, "request_clear", &request_clear, "request_okay", &request_okay, "request_cancel", &request_cancel, NULL); XtAddCallback(request_rr, XmNactivateCallback, qmonRequestEditResource, (XtPointer)0); XtAddCallback(request_hr, XmNactivateCallback, qmonRequestEditResource, (XtPointer)1); XtAddCallback(request_hr, XmNremoveCallback, qmonRequestRemoveResource, NULL); XtAddCallback(request_sr, XmNactivateCallback, qmonRequestEditResource, (XtPointer)1); XtAddCallback(request_sr, XmNremoveCallback, qmonRequestRemoveResource, NULL); XtAddCallback(request_hardsoft, XmtNvalueChangedCallback, qmonToggleHardSoft2, NULL); XtAddCallback(request_clear, XmNactivateCallback, qmonRequestClear, NULL); XtAddCallback(request_okay, XmNactivateCallback, qmonRequestOkay, NULL); XtAddCallback(request_cancel, XmNactivateCallback, qmonRequestCancel, NULL); XtAddEventHandler(XtParent(request_dialog), StructureNotifyMask, False, SetMinShellSize, NULL); } /* ** set the type labelString */ XtVaSetValues(request_rtype, XmtNlabel, qmonSubmitRequestType(), NULL); qmonMirrorMultiAnswer(CENTRY_T, &alp); if (alp) { qmonMessageBox(w, alp, 0); lFreeList(&alp); /* set normal cursor */ XmtDisplayDefaultCursor(w); DEXIT; return; } rll = qmonGetResources(qmonMirrorList(SGE_CE_LIST), REQUESTABLE_RESOURCES); hrl = qmonSubmitHR(); lFreeList(&hard_requests); if (hrl) { hard_requests = lCopyList("hr", hrl); for_each(ep, hard_requests) { rp = lGetElemStr(rll, CE_name, lGetString(ep, CE_name)); if (!rp) rp = lGetElemStr(rll, CE_shortcut, lGetString(ep, CE_name)); if (rp) { lSetString(ep, CE_name, lGetString(rp, CE_name)); lSetString(ep, CE_default, NULL); lSetUlong(ep, CE_valtype, lGetUlong(rp, CE_valtype)); } } }
/*-------------------------------------------------------------------------*/ static void qmonManopDelete(Widget w, XtPointer cld, XtPointer cad) { int type = dialog_mode; lList *lp = NULL; lList *alp = NULL; lEnumeration *what = NULL; lDescr *dp; int nm; int rows, i; DENTER(GUI_LAYER, "qmonManopDelete"); switch (type) { case SGE_UM_LIST: lp = XmStringToCull(manager_list, UM_Type, UM_name, SELECTED_ITEMS); dp = UM_Type; nm = UM_name; break; case SGE_UO_LIST: lp = XmStringToCull(operator_list, UO_Type, UO_name, SELECTED_ITEMS); dp = UO_Type; nm = UO_name; break; case SGE_UU_LIST: rows = XbaeMatrixNumRows(user_matrix); for (i=0; i<rows; i++) { String s = XbaeMatrixGetCell(user_matrix, i, 0); if (XbaeMatrixIsRowSelected(user_matrix, i) && s && strcmp(s, "")) lAddElemStr(&lp, UU_name, s, UU_Type); } XbaeMatrixDeselectAll(user_matrix); dp = UU_Type; nm = UU_name; break; case SGE_US_LIST: qmonUsersetDelete(w, NULL, NULL); DEXIT; return; default: DEXIT; return; } if (lp) { what = lWhat("%T(ALL)", dp); alp = qmonDelList(type, qmonMirrorListRef(type), nm, &lp, NULL, what); qmonMessageBox(w, alp, 0); updateManopList(); lFreeList(&alp); lFreeList(&lp); lFreeWhat(&what); } DEXIT; }
static void do_test(bool unique_hash, bool non_unique_hash, int num_objects, int num_names) { lList *lp = NULL; lList *copy; lListElem *ep; clock_t now, start; struct tms tms_buffer; #ifdef MALLINFO struct mallinfo meminfo; #endif int i; #ifdef HASH_STATISTICS cull_htable cht; dstring stat_dstring = DSTRING_INIT; #endif /* measurement data */ double prof_create, /* create objects */ prof_copy, /* copy list including all hashtables */ prof_rau, /* random access by unique attrib */ prof_inu, /* iterate by non unique attrib */ prof_curo, /* change unique attrib of random object */ prof_cnuro, /* change non unique attrib of random object */ prof_dru, /* delete random object by unique attribute */ prof_dinu; /* delete by iterating over non unique attrib */ int objs_dru, /* objects deleted by random unique */ objs_dinu; /* objects deleted by iterate non unique */ /* create list and hash tables */ lp = lCreateList("test list ", DESCR); if (unique_hash) { cull_hash_new(lp, NM_ULONG, true); } if (non_unique_hash) { cull_hash_new(lp, NM_STRING, false); } #ifdef HASH_STATISTICS cht = lp->descr[1].ht; printf("%s\n", cull_hash_statistics(cht, &stat_dstring)); #endif start = times(&tms_buffer); /* TEST: build objects */ for (i = 0; i < num_objects; i++) { ep = lAddElemUlong(&lp, NM_ULONG, i, DESCR); lSetString(ep, NM_STRING, names[rand() % num_names]); } /* measure time */ now = times(&tms_buffer); prof_create = (now - start) * 1.0 / clk_tck; #ifdef HASH_STATISTICS printf("%s\n", cull_hash_statistics(cht, &stat_dstring)); #endif /* measure memory usage */ #ifdef MALLINFO meminfo = mallinfo(); #endif /* TEST: copy list */ start = times(&tms_buffer); copy = lCopyList("copy", lp); /* measure time */ now = times(&tms_buffer); prof_copy = (now - start) * 1.0 / clk_tck; lFreeList(©); /* TEST: random access by unique attrib */ start = times(&tms_buffer); for (i = 0; i < num_objects; i++) { ep = lGetElemUlong(lp, NM_ULONG, rand() % num_objects); } /* measure time */ now = times(&tms_buffer); prof_rau = (now - start) * 1.0 / clk_tck; start = now; /* TEST: iterate by non unique attrib */ for (i = 0; i < num_names; i++) { const void *iterator = NULL; lListElem *next_ep; next_ep = lGetElemStrFirst(lp, NM_STRING, names[i], &iterator); while ((ep = next_ep) != NULL) { next_ep = lGetElemStrNext(lp, NM_STRING, names[i], &iterator); } } /* measure time */ now = times(&tms_buffer); prof_inu = (now - start) * 1.0 / clk_tck; start = now; /* TEST: change unique attribute of random object */ /* measure time */ for (i = 0; i < num_objects; i++) { /* object to access */ int unique = rand() % num_objects; /* new value to set, make sure we stay unique */ int newval = unique + num_objects; /* search object */ ep = lGetElemUlong(lp, NM_ULONG, unique); /* set a new value */ lSetUlong(ep, NM_ULONG, newval); /* restore old value */ lSetUlong(ep, NM_ULONG, unique); } now = times(&tms_buffer); prof_curo = (now - start) * 1.0 / clk_tck; start = now; /* TEST: change non unique attribute of random object */ for (i = 0; i < num_objects; i++) { /* search object */ ep = lGetElemUlong(lp, NM_ULONG, rand() % num_objects); /* set a new value */ lSetString(ep, NM_STRING, names[rand() % num_names]); } /* measure time */ now = times(&tms_buffer); prof_cnuro = (now - start) * 1.0 / clk_tck; start = now; /* TEST: delete random object */ objs_dru = 0; for (i = 0; i < num_objects / 2; i++) { /* search object */ ep = lGetElemUlong(lp, NM_ULONG, rand() % num_objects); /* if same rand showed up earlier, object does no longer exist! */ if (ep != NULL) { lRemoveElem(lp, &ep); objs_dru++; } } /* measure time */ now = times(&tms_buffer); prof_dru = (now - start) * 1.0 / clk_tck; start = now; /* TEST: delete all objects having the same non unique attribute */ objs_dinu = 0; for (i = 0; i < num_names; i++) { const void *iterator = NULL; lListElem *next_ep; next_ep = lGetElemStrFirst(lp, NM_STRING, names[i], &iterator); while ((ep = next_ep) != NULL) { next_ep = lGetElemStrNext(lp, NM_STRING, names[i], &iterator); lRemoveElem(lp, &ep); objs_dinu++; } } /* measure time */ now = times(&tms_buffer); prof_dinu = (now - start) * 1.0 / clk_tck; start = now; printf(DATA_FORMAT, unique_hash ? " * " : " ", non_unique_hash ? " * " : " ", prof_create, prof_copy, prof_rau, prof_inu, prof_curo, prof_cnuro, prof_dru, objs_dru, prof_dinu, objs_dinu, #ifdef MALLINFO (meminfo.usmblks + meminfo.uordblks) / 1024 #else 0L #endif ); #ifdef HASH_STATISTICS printf("%s\n", cull_hash_statistics(cht, &stat_dstring)); sge_dstring_free(&stat_dstring); #endif lFreeList(&lp); }
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(¬hing); 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 */ }
/****** execd/sge_execd_register_at_qmaster() ********************************** * NAME * sge_execd_register_at_qmaster() -- modify execd list at qmaster site * * SYNOPSIS * int sge_execd_register_at_qmaster(void) * * FUNCTION * add local execd name to SGE_EH_LIST in order to register at * qmaster * * INPUTS * void - no input * * RESULT * int - 0 = success / 1 = error * * NOTES * MT-NOTE: sge_execd_register_at_qmaster() is not MT safe * *******************************************************************************/ int sge_execd_register_at_qmaster(sge_gdi_ctx_class_t *ctx, bool is_restart) { int return_value = 0; static int sge_last_register_error_flag = 0; lList *alp = NULL; /* * If it is a reconnect (is_restart == true) the act_qmaster file must be * re-read in order to update ctx qmaster cache when master migrates. */ const char *master_host = ctx->get_master(ctx, is_restart); DENTER(TOP_LAYER, "sge_execd_register_at_qmaster"); /* We will not try to make a gdi request when qmaster is not alive. The * gdi will return with timeout after one minute. If qmaster is not alive * we will not try a gdi request! */ if (master_host != NULL && ctx->is_alive(ctx) == CL_RETVAL_OK) { lList *hlp = lCreateList("exechost starting", EH_Type); lListElem *hep = lCreateElem(EH_Type); lSetUlong(hep, EH_featureset_id, feature_get_active_featureset_id()); lAppendElem(hlp, hep); /* register at qmaster */ DPRINTF(("***** Register at qmaster *****\n")); if (!is_restart) { /* * This is a regular startup. */ alp = ctx->gdi(ctx, SGE_EH_LIST, SGE_GDI_ADD, &hlp, NULL, NULL); } else { /* * Indicate this is a restart to qmaster. * This is used for the initial_state of queue_configuration implementation. */ alp = ctx->gdi(ctx, SGE_EH_LIST, SGE_GDI_ADD | SGE_GDI_EXECD_RESTART, &hlp, NULL, NULL); } lFreeList(&hlp); } else { DPRINTF(("***** Register at qmaster - qmaster not alive! *****\n")); } if (alp == NULL) { if (sge_last_register_error_flag == 0) { WARNING((SGE_EVENT, MSG_COM_CANTREGISTER_SS, master_host?master_host:"", MSG_COM_ERROR)); sge_last_register_error_flag = 1; } return_value = 1; } else { lListElem *aep = lFirst(alp); if (lGetUlong(aep, AN_status) != STATUS_OK) { if (sge_last_register_error_flag == 0) { WARNING((SGE_EVENT, MSG_COM_CANTREGISTER_SS, master_host?master_host:"", lGetString(aep, AN_text))); sge_last_register_error_flag = 1; } return_value = 1; } } if (return_value == 0) { sge_last_register_error_flag = 0; INFO((SGE_EVENT, MSG_EXECD_REGISTERED_AT_QMASTER_S, master_host?master_host:"")); last_qmaster_registration_time = sge_get_gmt(); } lFreeList(&alp); DRETURN(return_value); }
/****** sge_select_queue/get_attribute() *************************************** * NAME * get_attribute() -- looks for an attribut, but only for one level (for host, global, or queue) * * SYNOPSIS * static lListElem* get_attribute(const char *attrname, lList *config_attr, * lList *actual_attr, lList *load_attr, lList *centry_list, lListElem * *queue, lListElem *rep, u_long32 layer, double lc_factor, dstring *reason) * * FUNCTION * Extracts the attribut specified with 'attrname' and finds the * more important one, if it is defined multiple times on the same * level. It only cares about one level. * If the attribute is a consumable, one can specify a point in time and a duration. * This will get the caller the min amount of that resource during the time frame. * * INPUTS * const char *attrname - attribute name one is looking for * lList *config_attr - user defined attributes (CE_Type) * lList *actual_attr - current usage of consumables (RUE_Type) * lList *load_attr - load attributes * lList *centry_list - the system wide attribute configuration * lListElem *queue - the current queue, or null, if one works on hosts * u_long32 layer - the current layer * double lc_factor - the load correction value * dstring *reason - space for error messages or NULL * bool zero_utilization - ??? * u_long32 start_time - begin of the time interval, one asks for the resource * u_long32 duration - the duration the interval * * RESULT * static lListElem* - the element one was looking for or NULL * *******************************************************************************/ lListElem* get_attribute(const char *attrname, lList *config_attr, lList *actual_attr, lList *load_attr, const lList *centry_list, lListElem *queue, u_long32 layer, double lc_factor, dstring *reason, bool zero_utilization, u_long32 start_time, u_long32 duration) { lListElem *actual_el=NULL; lListElem *load_el=NULL; lListElem *cplx_el=NULL; DENTER(BASIS_LAYER, "get_attribute"); /* resource_attr is a complex_entry (CE_Type) */ if (config_attr) { lListElem *temp = lGetElemStr(config_attr, CE_name, attrname); if (temp){ cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname)); if(!cplx_el){ /* error */ DRETURN(NULL); } lSetUlong(cplx_el, CE_dominant, layer | DOMINANT_TYPE_FIXED); lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE); /* default, no value set */ lSetDouble(cplx_el, CE_doubleval, lGetDouble(temp,CE_doubleval) ); lSetString(cplx_el, CE_stringval, lGetString(temp,CE_stringval) ); } } if (cplx_el && lGetUlong(cplx_el, CE_consumable) != CONSUMABLE_NO) { lSetUlong(cplx_el, CE_pj_dominant, layer | DOMINANT_TYPE_CONSUMABLE); lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); /* treat also consumables as fixed attributes when assuming an empty queuing system */ if (sconf_get_qs_state() == QS_STATE_FULL) { if (actual_attr && (actual_el = lGetElemStr(actual_attr, RUE_name, attrname))){ dstring ds; char as_str[20]; double utilized = zero_utilization ? 0 : utilization_max(actual_el, start_time, duration, false); switch (lGetUlong(cplx_el, CE_relop)) { case CMPLXGE_OP: case CMPLXGT_OP: lSetDouble(cplx_el, CE_pj_doubleval, utilized); break; case CMPLXEQ_OP: case CMPLXLT_OP: case CMPLXLE_OP: case CMPLXNE_OP: default: lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval) - utilized); break; } sge_dstring_init(&ds, as_str, sizeof(as_str)); sge_dstring_sprintf(&ds, "%8.3f", (float)lGetDouble(cplx_el, CE_pj_doubleval)); lSetString(cplx_el,CE_pj_stringval, as_str); } else{ sge_dstring_sprintf(reason, MSG_ATTRIB_ACTUALELEMENTTOATTRIBXMISSING_S, attrname); lFreeElem(&cplx_el); DRETURN(NULL); } } else{ lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval)); lSetString(cplx_el,CE_pj_stringval, lGetString(cplx_el, CE_stringval)); } } /** check for a load value */ if (load_attr && (load_el = lGetElemStr(load_attr, HL_name, attrname)) && (sconf_get_qs_state()==QS_STATE_FULL || lGetBool(load_el, HL_static)) && (!is_attr_prior(cplx_el, cplx_el))) { lListElem *ep_nproc=NULL; int nproc=1; if (!cplx_el){ cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname)); if (!cplx_el){ /* error */ DRETURN(NULL); } lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE); } if ((ep_nproc = lGetElemStr(load_attr, HL_name, LOAD_ATTR_NUM_PROC))) { const char *cp = lGetString(ep_nproc, HL_value); if (cp) nproc = MAX(1, atoi(lGetString(ep_nproc, HL_value))); } { const char *load_value=NULL; u_long32 type; double dval; load_value = lGetString(load_el, HL_value); /* are we working on string values? if though, than it is easy */ if ( (type = lGetUlong(cplx_el, CE_valtype)) == TYPE_STR || type == TYPE_CSTR || type == TYPE_HOST || type == TYPE_RESTR) { lSetString(cplx_el, CE_stringval, load_value); lSetUlong(cplx_el, CE_dominant, layer | DOMINANT_TYPE_LOAD); } else { /* working on numerical values */ lListElem *job_load; char err_str[256]; char sval[100]; u_long32 dom_type = DOMINANT_TYPE_LOAD; lList *load_adjustments = sconf_get_job_load_adjustments(); job_load=lGetElemStr(load_adjustments, CE_name, attrname); if (parse_ulong_val(&dval, NULL, type, load_value, NULL, 0)) { sge_strlcpy(sval, load_value, 100); /* -------------------------------- look for 'name' in our load_adjustments list */ if (job_load) { const char *s; double load_correction; s = lGetString(job_load, CE_stringval); if (!parse_ulong_val(&load_correction, NULL, type, s, err_str, 255)) { ERROR((SGE_EVENT, MSG_SCHEDD_LOADADJUSTMENTSVALUEXNOTNUMERIC_S , attrname)); } else if (lc_factor) { double old_dval; u_long32 relop; if (!strncmp(attrname, "np_", 3) && nproc != 1 ) { DPRINTF(("fillComplexFromHost: dividing lc_factor for \"%s\" with value %f by %d to %f\n", attrname, lc_factor, nproc, lc_factor / nproc)); lc_factor /= nproc; } load_correction *= lc_factor; /* it depends on relop in complex config whether load_correction is pos/neg */ if ( (relop = lGetUlong(cplx_el, CE_relop)) == CMPLXGE_OP || relop == CMPLXGT_OP){ old_dval = dval; dval += load_correction; } else{ old_dval = dval; dval -= load_correction; } sprintf(sval, "%8.3f", dval); DPRINTF(("%s: uc: %f c(%f): %f\n", attrname, old_dval, lc_factor, dval)); dom_type = DOMINANT_TYPE_CLOAD; } } /* we can have a user, who wants to override the incomming load value. This is no problem for consumables, but for fixed values. A custom fixed value is a per slot value (stored in CE_doubleval) and a load value is a per job value (stored in CE_pj_doubleval). This code changes a fixed custom value from a per slot to a per job value!! */ if ( !(lGetUlong(cplx_el, CE_dominant) == DOMINANT_TYPE_VALUE) && (lGetUlong(cplx_el, CE_pj_dominant) == DOMINANT_TYPE_VALUE)){ lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval)); lSetString(cplx_el, CE_pj_stringval, lGetString(cplx_el, CE_stringval)); lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); lSetUlong(cplx_el, CE_pj_dominant, layer | DOMINANT_TYPE_FIXED); } if (!is_attr_prior2(cplx_el, dval, CE_pj_doubleval, CE_pj_dominant)){ lSetString(cplx_el, CE_pj_stringval, load_value); lSetUlong(cplx_el, CE_pj_dominant, layer | dom_type); lSetDouble(cplx_el, CE_pj_doubleval, dval ); } } /* end numerical load value */ lFreeList(&load_adjustments); }/* end block */ } } /* we are working on queue level, so we have to check for queue resource values */ if (queue){ bool created=false; if(!cplx_el){ cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname)); if(!cplx_el){ /* error */ DRETURN(NULL); } lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE); lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE); created = true; } if (!get_queue_resource(cplx_el, queue, attrname) && created) { lFreeElem(&cplx_el); } } DRETURN(cplx_el); }
/*-------------------------------------------------------------------------*/ static void qmonUserAskForProject(Widget w, XtPointer cld, XtPointer cad) { XbaeMatrixLabelActivateCallbackStruct *cbs = (XbaeMatrixLabelActivateCallbackStruct *) cad; Boolean status = False; lList *pl = NULL; lListElem *cep = NULL; int n, i; StringConst *strs = NULL; static char buf[BUFSIZ]; lList *lp = NULL; lList *alp = NULL; lListElem *ep; static lEnumeration *what = NULL; DENTER(GUI_LAYER, "qmonUserAskForProject"); if (!what) { what = lWhat("%T(%I %I)", UU_Type, UU_name, UU_default_project); } if (cbs->column != 1) { DEXIT; return; } qmonMirrorMultiAnswer(PROJECT_T, &alp); if (alp) { qmonMessageBox(w, alp, 0); lFreeList(&alp); DEXIT; return; } pl = qmonMirrorList(SGE_PR_LIST); lPSortList(pl, "%I+", PR_name); n = lGetNumberOfElem(pl); if (n>0) { strs = (StringConst*)XtMalloc(sizeof(String)*(n+1)); strs[0] = "NONE"; for (cep=lFirst(pl), i=0; i<n; cep=lNext(cep), i++) { /* ** we get only references don't free, the strings */ strs[i+1] = lGetString(cep, PR_name); } strcpy(buf, ""); /* FIX_CONST_GUI */ status = XmtAskForItem(w, NULL, "@{Select a project}", "@{Available projects}", (String*)strs, n+1, False, buf, BUFSIZ, NULL); if (status) { int rows, i; rows = XbaeMatrixNumRows(user_matrix); for (i=0; i<rows; i++) { String s = XbaeMatrixGetCell(user_matrix, i, 0); if (XbaeMatrixIsRowSelected(user_matrix, i) && s && strcmp(s, "")) { ep = lAddElemStr(&lp, UU_name, s, UU_Type); lSetString(ep, UU_default_project, buf); } } XbaeMatrixDeselectAll(user_matrix); /* ** send to master as modify request */ for_each (ep, lp) { if (ep && lGetString(ep, UU_default_project) && !strcasecmp(lGetString(ep, UU_default_project), "NONE")) lSetString(ep, UU_default_project, NULL); } if (lp) { alp = qmonModList(SGE_UU_LIST, qmonMirrorListRef(SGE_UU_LIST), UU_name, &lp, NULL, what); qmonMessageBox(w, alp, 0); updateManopList(); lFreeList(&alp); lFreeList(&lp); } } /* ** don't free referenced strings, they are in the pl list */ XtFree((char*)strs); }
/****** 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; }
/******************************************************** ensure - all nodes have a unique path in share tree - a project is not referenced more than once in share tree - a user appears only once in a project sub-tree - a user appears only once outside of a project sub-tree - a user does not appear as a non-leaf node - all leaf nodes in a project sub-tree reference a known user object or the reserved name "default" - there are no sub-projects within a project sub-tree - all leaf nodes not in a project sub-tree reference a known user or project object - all user leaf nodes in a project sub-tree have access to the project ********************************************************/ int check_sharetree( lList **alpp, lListElem *node, lList *user_list, lList *project_list, lListElem *project, lList **found /* tmp list that contains one entry for each found u/p */ ) { lList *children; lListElem *child, *remaining; lList *save_found = NULL; const char *name = lGetString(node, STN_name); lListElem *pep; DENTER(TOP_LAYER, "check_sharetree"); /* Check for dangling or circular references. */ if (name == NULL) { ERROR((SGE_EVENT, MSG_STREE_NOVALIDNODEREF_U, sge_u32c(lGetUlong(node, STN_id)))); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DEXIT; return -1; } if ((children=lGetList(node, STN_children))) { /* not a leaf node */ /* check if this is a project node */ if ((pep=prj_list_locate(project_list, name))) { /* check for sub-projects (not allowed) */ if (project) { ERROR((SGE_EVENT, MSG_STREE_PRJINPTJSUBTREE_SS, name, lGetString(project, PR_name))); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DEXIT; return -1; } /* check for projects appearing more than once */ if (lGetElemStr(*found, STN_name, name)) { ERROR((SGE_EVENT, MSG_STREE_PRJTWICE_S, name)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DEXIT; return -1; } /* register that this project was found */ lAddElemStr(found, STN_name, name, STN_Type); /* set up for project sub-tree recursion */ project = pep; save_found = *found; *found = NULL; /* check for user appearing as non-leaf node */ } else if (user_list_locate(user_list, name)) { ERROR((SGE_EVENT, MSG_STREE_USERNONLEAF_S, name)); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); DEXIT; return -1; } for_each(child, children) { /* ensure pathes are identically inside share tree */ for (remaining=lNext(child); remaining; remaining=lNext(remaining)) { const char *cn = lGetString(child, STN_name); const char *rn = lGetString(remaining, STN_name); if (cn == NULL || rn == NULL) { ERROR((SGE_EVENT, MSG_GDI_KEYSTR_NULL_S, "STN_name")); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); /* restore old found list */ if (save_found) { lFreeList(found); *found = save_found; } DEXIT; return -1; } if (!strcmp(cn, rn)) { ERROR((SGE_EVENT, MSG_SGETEXT_FOUND_UP_TWICE_SS, cn, lGetString(node, STN_name))); answer_list_add(alpp, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); /* restore old found list */ if (save_found) { lFreeList(found); *found = save_found; } DEXIT; return -1; } } if (check_sharetree(alpp, child, user_list, project_list, project, found)) { /* restore old found list */ if (save_found) { lFreeList(found); *found = save_found; } DEXIT; return -1; } } /* restore old found list */ if (save_found) { lFreeList(found); *found = save_found; } } else { /* a leaf node */ /* check if this is a project node */ if (prj_list_locate(project_list, name)) {
/****** 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); }
static void qmonRQSGetText(Widget tw, lList *rqs_list, lList **alpp) { char *text = NULL; lList *new_rqs_list = NULL; char filename[SGE_PATH_MAX] = ""; size_t len = 0; bool ret = false; bool ignore_unchanged_message = false; dstring sge_tmpnam_error = DSTRING_INIT; DENTER(GUI_LAYER, "qmonRQSGetText"); if (sge_tmpnam(filename, &sge_tmpnam_error) == NULL) { if (sge_dstring_get_string(&sge_tmpnam_error) != NULL) { answer_list_add(alpp, sge_dstring_get_string(&sge_tmpnam_error), STATUS_ERROR1, ANSWER_QUALITY_ERROR); } else { answer_list_add(alpp, MSG_POINTER_NULLPARAMETER, STATUS_ERROR1, ANSWER_QUALITY_ERROR); } sge_dstring_free(&sge_tmpnam_error); DEXIT; return; } sge_dstring_free(&sge_tmpnam_error); /* ** allocates a string */ text = XmTextGetString(tw); len = strlen(text); ret = sge_string2file(text, len, filename); XtFree(text); new_rqs_list = spool_flatfile_read_list(alpp, RQS_Type, RQS_fields, NULL, true, &qconf_rqs_sfi, SP_FORM_ASCII, NULL, filename); if (answer_list_output(alpp)) { lFreeList(&new_rqs_list); } if (new_rqs_list != NULL) { if (ignore_unchanged_message || object_list_has_differences(new_rqs_list, alpp, rqs_list, false)) { ret = true; } else { lFreeList(&new_rqs_list); answer_list_add(alpp, MSG_FILE_NOTCHANGED, STATUS_ERROR1, ANSWER_QUALITY_ERROR); } } else { answer_list_add(alpp, MSG_FILE_ERRORREADINGINFILE, STATUS_ERROR1, ANSWER_QUALITY_ERROR); } unlink(filename); if (ret) { ret = rqs_add_del_mod_via_gdi(ctx, new_rqs_list, alpp, SGE_GDI_REPLACE); } lFreeList(&new_rqs_list); DEXIT; }