/****** shepherd_binding/create_binding_env() **************************** * NAME * create_binding_env() -- Creates SGE_BINDING env variable. * * SYNOPSIS * bool create_binding_env(hwloc_const_bitmap_t set) * * FUNCTION * Creates the SGE_BINDING environment variable. * This environment variable contains a space-separated list of * internal processor ids given as input parameter. * * INPUTS * hwloc_const_bitmap_t set - CPU set to use * * RESULT * bool - true when SGE_BINDING env var could be generated false if not * * NOTES * MT-NOTE: create_binding_env() is MT safe * *******************************************************************************/ static bool create_binding_env(hwloc_const_bitmap_t set) { bool retval = true; dstring sge_binding = DSTRING_INIT; dstring proc = DSTRING_INIT; unsigned i; bool first = true; hwloc_bitmap_foreach_begin(i, set) if (first) { first = false; sge_dstring_sprintf(&proc, "%d", i); } else { sge_dstring_sprintf(&proc, " %d", i); } sge_dstring_append_dstring(&sge_binding, &proc); hwloc_bitmap_foreach_end(); if (sge_setenv("SGE_BINDING", sge_dstring_get_string(&sge_binding)) != 1) { /* settting env var was not successful */ retval = false; shepherd_trace("create_binding_env: Couldn't set environment variable!"); } sge_dstring_free(&sge_binding); sge_dstring_free(&proc); return retval; }
bool shepherd_write_pid_file(pid_t pid, dstring *errmsg) { bool ret = true; FILE *fp = NULL; fp = fopen("pid", "w"); if (fp != NULL) { if (fprintf(fp, pid_t_fmt"\n", pid) < 0) { sge_dstring_sprintf(errmsg, MSG_FILE_CANNOT_WRITE_SS, "pid", strerror(errno)); ret = false; } else { if (fflush(fp) < 0) { sge_dstring_sprintf(errmsg, MSG_FILE_CANNOT_FLUSH_SS, "pid", strerror(errno)); ret = false; } } FCLOSE(fp); } else { sge_dstring_sprintf(errmsg, MSG_FILE_NOOPEN_SS, "pid", strerror(errno)); ret = false; } return ret; FCLOSE_ERROR: sge_dstring_sprintf(errmsg, MSG_FILE_NOCLOSE_SS, "pid", strerror(errno)); return false; }
/*-------------------------------------------------------------------------*/ static void qmonCalendarFillConf( Widget w, lListElem *ep ) { XmString *items; Cardinal itemCount; const char *s; int i; dstring sb = DSTRING_INIT; DENTER(GUI_LAYER, "qmonCalendarFillConf"); if (!ep) { /* ** clear the cal_conf_list */ XtVaSetValues( cal_conf_list, XmNitems, NULL, XmNitemCount, 0, NULL); DEXIT; return; } itemCount = 2; items = (XmString*) XtMalloc(sizeof(XmString)*itemCount); i = 0; /* year calendar */ sge_dstring_sprintf(&sb, "%-20.20s ", XmtLocalize(w, "Year", "Year")); sge_dstring_append(&sb, (s=lGetString(ep, CAL_year_calendar))?s: XmtLocalize(w, "NONE", "NONE")); items[i++] = XmStringCreateLtoR(sb.s, "LIST"); sge_dstring_free(&sb); /* week calendar */ sge_dstring_sprintf(&sb, "%-20.20s ", XmtLocalize(w, "Week", "Week")); sge_dstring_append(&sb, (s=lGetString(ep, CAL_week_calendar))?s: XmtLocalize(w, "NONE", "NONE")); items[i++] = XmStringCreateLtoR((char*)sge_dstring_get_string(&sb), "LIST"); sge_dstring_free(&sb); XtVaSetValues( cal_conf_list, XmNitems, items, XmNitemCount, itemCount, NULL); XmStringTableFree(items, itemCount); DEXIT; }
/****** sge_client_ijs/force_ijs_server_shutdown() ***************************** * NAME * force_ijs_server_shutdown() -- forces the commlib server for the builtin * interactive job support to shut down * * SYNOPSIS * int force_ijs_server_shutdown(COMM_HANDLE **phandle, const char * *this_component, dstring *p_err_msg) * * FUNCTION * Forces the commlib server for the builtin interactive job support to shut * down immediately and ensures it is shut down. * * INPUTS * COMM_HANDLE **phandle - Handle of the COMM connection, gets set to * NULL in this function. * const char *this_component - Name of this component. * dstring *p_err_msg - Contains the error reason in case of error. * * RESULT * int - 0: OK * 1: Invalid parameter: phandle == NULL or *phandle == NULL * 2: Can't shut down connection, see p_err_msg for details * * NOTES * MT-NOTE: force_ijs_server_shutdown() is not MT safe * * SEE ALSO * sge_client_ijs/start_ijs_server() * sge_client_ijs/run_ijs_server() * sge_client_ijs/stop_ijs_server_shutdown() *******************************************************************************/ int force_ijs_server_shutdown(COMM_HANDLE **phandle, const char *this_component, dstring *p_err_msg) { int ret; DENTER(TOP_LAYER, "force_ijs_server_shutdown"); if (phandle == NULL || *phandle == NULL) { sge_dstring_sprintf(p_err_msg, "invalid connection handle"); DPRINTF(("invalid connection handle - nothing to shut down\n")); DRETURN(1); } DPRINTF(("connection is still alive\n")); /* This will remove the handle */ ret = comm_shutdown_connection(*phandle, COMM_CLIENT, g_hostname, p_err_msg); sge_free(&g_hostname); if (ret != COMM_RETVAL_OK) { DPRINTF(("comm_shutdown_connection() failed: %s (%d)\n", sge_dstring_get_string(p_err_msg), ret)); ret = 2; } else { DPRINTF(("successfully shut down the connection\n")); } *phandle = NULL; DRETURN(ret); }
/****** uti/dstring/sge_dstring_strip_white_space_at_eol() ********************* * NAME * sge_dstring_strip_white_space_at_eol() -- as it says * * SYNOPSIS * void sge_dstring_strip_white_space_at_eol(dstring *string) * * FUNCTION * removes whitespace at the end of the given "string". * * INPUTS * dstring *string - dstring *******************************************************************************/ void sge_dstring_strip_white_space_at_eol(dstring *string) { DENTER(DSTRING_LAYER, "sge_strip_white_space_at_eol"); if (string != NULL) { char *s = (string != NULL) ? string->s : NULL; if (s != NULL) { sge_strip_white_space_at_eol(s); } } DRETURN_VOID; } #if 0 /* EB: DEBUG: */ int main(void) { char *s; dstring sb = DSTRING_INIT; /* initialize */ /* * change content */ s = sge_dstring_append(&sb, "Trala"); s = sge_dstring_append(&sb, " trolo"); s = sge_dstring_append(&sb, " troet"); s = sge_dstring_sprintf(&sb, "%d, %s, %f\n", 5, "rabarber ", 5.6); /* * use string */ printf("%s\n", s); printf("%s\n", sge_dstring_get_string(&sb)); /* * free the string when no longer needed */ sge_dstring_free(&sb); return 0; }
/****** shepherd_binding/create_binding_env_linux() **************************** * NAME * create_binding_env_linux() -- Creates SGE_BINDING env variable. * * SYNOPSIS * bool create_binding_env_linux(const int* proc_id, const int amount) * * FUNCTION * Creates the SGE_BINDING environment variable on Linux operating system. * This environment variable contains a space separated list of Linux * internal processor ids given as input parameter. * * INPUTS * const int* proc_id - List of processor ids. * const int amount - Length of processor id list. * * RESULT * bool - true when SGE_BINDING env var could be generated false if not * * NOTES * MT-NOTE: create_binding_env_linux() is MT safe * *******************************************************************************/ bool create_binding_env_linux(const int* proc_id, const int amount) { bool retval = true; dstring sge_binding = DSTRING_INIT; dstring proc = DSTRING_INIT; int i; for (i = 0; i < amount; i++) { sge_dstring_clear(&proc); /* DG TODO env ends with whitespace char */ sge_dstring_sprintf(&proc, "%d ", proc_id[i]); sge_dstring_append_dstring(&sge_binding, &proc); } if (sge_setenv("SGE_BINDING", sge_dstring_get_string(&sge_binding)) != 1) { /* settting env var was not successful */ retval = false; shepherd_trace("create_binding_env_linux: Couldn't set environment variable!"); } sge_dstring_free(&sge_binding); sge_dstring_free(&proc); return retval; }
void xml_addAttributeD(lListElem *xml_elem, const char *name, double value) { char buffer[20]=""; dstring string; sge_dstring_init(&string, buffer, 20); xml_addAttribute(xml_elem, name, sge_dstring_sprintf(&string, "%f", value)); }
/****** loadcheck/fill_socket_core_topology() ********************************** * NAME * fill_socket_core_topology() -- Get load values regarding processor topology. * * SYNOPSIS * void fill_socket_core_topology(dstring* msocket, dstring* mcore, dstring* * mtopology) * * FUNCTION * Gets the values regarding processor topology. * * OUTPUTS * dstring* msocket - The amount of sockets the host have. * dstring* mcore - The amount of cores the host have. * dstring* mtopology - The topology the host have. * * RESULT * void - nothing * *******************************************************************************/ void fill_socket_core_topology(dstring* msocket, dstring* mcore, dstring* mtopology) { int ms, mc; char* topo = NULL; int length = 0; ms = get_execd_amount_of_sockets(); mc = get_execd_amount_of_cores(); if (!get_execd_topology(&topo, &length) || topo == NULL) { topo = sge_strdup(NULL, "-"); } sge_dstring_sprintf(msocket, "%d", ms); sge_dstring_sprintf(mcore, "%d", mc); sge_dstring_append(mtopology, topo); sge_free(&topo); }
void sge_worker_initialize(sge_gdi_ctx_class_t *ctx) { const u_long32 max_initial_worker_threads = ctx->get_worker_thread_count(ctx); cl_thread_settings_t* dummy_thread_p = NULL; int i; DENTER(TOP_LAYER, "sge_worker_initialize"); /* * TODO: EB: corresponding destroy function is missing during shutdown */ sge_tq_create(&Master_Task_Queue); sge_init_job_number(); sge_init_ar_id(); DPRINTF(("job/ar counter have been initialized\n")); reporting_initialize(NULL); DPRINTF(("accounting and reporting module has been initialized\n")); INFO((SGE_EVENT, MSG_QMASTER_THREADCOUNT_US, sge_u32c(max_initial_worker_threads), threadnames[WORKER_THREAD])); cl_thread_list_setup(&(Main_Control.worker_thread_pool), "thread pool"); for (i = 0; i < max_initial_worker_threads; i++) { dstring thread_name = DSTRING_INIT; sge_dstring_sprintf(&thread_name, "%s%03d", threadnames[WORKER_THREAD], i); cl_thread_list_create_thread(Main_Control.worker_thread_pool, &dummy_thread_p, cl_com_get_log_list(), sge_dstring_get_string(&thread_name), i, sge_worker_main, NULL, NULL, CL_TT_WORKER); sge_dstring_free(&thread_name); } DRETURN_VOID; }
/****** sge_client_ijs/stop_ijs_server() *************************************** * NAME * stop_ijs_server() -- stops the commlib server for the builtin * interactive job support * * SYNOPSIS * int stop_ijs_server(COMM_HANDLE **phandle, dstring *p_err_msg) * * FUNCTION * Stops the commlib server for the commlib connection between the shepherd * of the interactive job (qrsh/qlogin) and the qrsh/qlogin command. * Over this connectin the stdin/stdout/stderr input/output is transferred. * * INPUTS * COMM_HANDLE **phandle - Pointer to the COMM server handle. Gets set to * NULL in this function. * dstring *p_err_msg - Contains the error reason in case of error. * * RESULT * int - 0: OK * 1: Invalid Parameter: phandle = NULL * 2: General error shutting down the COMM server, * see p_err_msg for details * * NOTES * MT-NOTE: stop_ijs_server() is not MT safe * * SEE ALSO * sge_client_ijs/start_ijs_server() * sge_client_ijs/run_ijs_server() * sge_client_ijs/force_ijs_server_shutdown() *******************************************************************************/ int stop_ijs_server(COMM_HANDLE **phandle, dstring *p_err_msg) { int ret = 0; DENTER(TOP_LAYER, "stop_ijs_server"); if (phandle == NULL) { ret = 1; } else if (*phandle != NULL) { cl_com_set_error_func(NULL); #if 0 cl_log_list_set_log_level(cl_com_get_log_list(), CL_LOG_OFF); #endif cl_com_ignore_timeouts(CL_TRUE); DPRINTF(("shut down the connection from our side\n")); ret = cl_commlib_shutdown_handle(*phandle, CL_FALSE); if (ret != CL_RETVAL_OK) { sge_dstring_sprintf(p_err_msg, "error shutting down the connection: %s", cl_get_error_text(ret)); ret = 2; } *phandle = NULL; } DRETURN(ret); }
static int spawn_file(dstring *aBuffer, dstring *error_message) { int my_errno; char* mktemp_return = NULL; char tmp_file_string[256]; char tmp_string[SGE_PATH_MAX]; /* * generate template filename for mktemp() */ snprintf(tmp_file_string, 256, "pid-%u-XXXXXX", (unsigned int)getpid()); /* * check final length of path */ if (sge_dstring_strlen(aBuffer) + strlen(tmp_file_string) >= SGE_PATH_MAX) { sge_dstring_append(aBuffer, tmp_file_string); sge_dstring_sprintf(error_message, MSG_TMPNAM_SGE_MAX_PATH_LENGTH_US, sge_u32c(SGE_PATH_MAX), sge_dstring_get_string(aBuffer)); return -1; } /* * now build full path string for mktemp() */ snprintf(tmp_string, SGE_PATH_MAX, "%s%s", sge_dstring_get_string(aBuffer), tmp_file_string); /* * generate temp file by call to mktemp() */ errno = 0; mktemp_return = mktemp(tmp_string); my_errno = errno; if (mktemp_return[0] == '\0') { sge_dstring_sprintf(error_message, MSG_TMPNAM_GOT_SYSTEM_ERROR_SS, strerror(my_errno), sge_dstring_get_string(aBuffer)); return -1; } /* * finally copy the resulting path to aBuffer */ sge_dstring_sprintf(aBuffer, tmp_string); return 0; }
/****** sgeobj/qinstance/qinstance_get_name() ********************************* * NAME * qinstance_get_name() -- returns the fullname of a qinstance object * * SYNOPSIS * const char * * qinstance_get_name(const lListElem *this_elem, * dstring *string_buffer) * * FUNCTION * Returns the fullname of a qinstance object * * INPUTS * const lListElem *this_elem - QU_Type * dstring *string_buffer - dynamic string buffer * * RESULT * const char * - pointer to the internal string buffer of "string_buffer" * * NOTES * MT-NOTE: qinstance_get_name() is MT safe *******************************************************************************/ const char * qinstance_get_name(const lListElem *this_elem, dstring *string_buffer) { const char *ret = NULL; if (this_elem != NULL && string_buffer != NULL) { ret = sge_dstring_sprintf(string_buffer, SFN"@"SFN, lGetString(this_elem, QU_qname), lGetHost(this_elem, QU_qhostname)); } return ret; }
/****** uti/stdlib/sge_setenv() *********************************************** * NAME * sge_setenv() -- Change or add an environment variable * * SYNOPSIS * int sge_setenv(const char *name, const char *value) * * FUNCTION * Change or add an environment variable * * INPUTS * const char *name - variable name * const char *value - new value * * RESULT * int - error state * 1 - success * 0 - error * * SEE ALSO * uti/stdlib/sge_putenv() * uti/stdlib/sge_getenv() * uti/stdio/addenv() * * NOTES * MT-NOTE: sge_setenv() is MT safe *******************************************************************************/ int sge_setenv(const char *name, const char *value) { int ret = 0; if (name != NULL && value != NULL) { dstring variable = DSTRING_INIT; sge_dstring_sprintf(&variable, "%s=%s", name, value); ret = sge_putenv(sge_dstring_get_string(&variable)); sge_dstring_free(&variable); } return ret; }
/****** shepherd/shepconf/shepconf_has_notify_signal() ************************ * NAME * shepconf_has_notify_signal() -- Do we have a notification signal * * SYNOPSIS * int shepconf_has_notify_signal(char *notify_name, int *signal) * * FUNCTION * This function checks if the notification mechanism is enabled. * In this case the function will retuen 'true' and it will * return the default signal or the user defined signal for * the given "notify_name". * * INPUTS * char *notify_name - "notify_susp" or "notify_kill" * int *signal - signal id * * RESULT * int - true or false *******************************************************************************/ int shepconf_has_notify_signal(const char *notify_name, int *signal) { const char *notify_array[] = { "notify_susp", "notify_kill", NULL }; int signal_array[] = { SIGUSR1, SIGUSR2, 0 }; dstring param_name = DSTRING_INIT; char *conf_type = NULL; int conf_id; int ret = 0; /* * There are three possibilities: * a) There is a user defined signal which should be used * b) Default signal should be used * c) Notification mechanism is disabled */ sge_dstring_sprintf(¶m_name, "%s%s", notify_name, "_type"); conf_type = search_conf_val(sge_dstring_get_string(¶m_name)); sge_dstring_free(¶m_name); if (conf_type != NULL) { conf_id = atol(conf_type); } else { conf_id = 1; /* Default signal should be used */ } if (conf_id == 0) { char *conf_signal = search_conf_val(notify_name); if (conf_signal != NULL) { *signal = sge_sys_str2signal(conf_signal); ret = 1; } } else if (conf_id == 1) { int i; for (i = 0; notify_array[i] != NULL; i++) { if (!strcmp(notify_array[i], notify_name)) { break; } } *signal = signal_array[i]; ret = 1; } else { *signal = 0; ret = 0; } return ret; }
/****** uti/sge_tmpnam/sge_tmpnam() ******************************************* * NAME * sge_tmpnam() -- Secure replacement for tmpnam() * * SYNOPSIS * char* sge_tmpnam(char *aBuffer) * * FUNCTION * Generate a string that is a unique valid filename within a given * directory. The corresponding file is created as soon as the filename * has been generated, thus avoiding any delay between filename generation * and actual file usage. The file will have read and write access for the * user only. * * The 'aBuffer' argument points to an array of at least SGE_PATH_MAX length. * 'aBuffer' will contain the generated filename upon successful completion. * In addition, 'aBuffer' will be returned. If the function fails, NULL will * be returned and 'errno' set to indicate the error. * * If the environment variable TMPDIR is defined, it's value will be used * as the path prefix for the file. If TMPDIR is not set or it does not * refer to a valid directory, the value of P_tmpdir will be used. * P_tmpdir shall be defined in <stdio.h>. If P_tmpdir is not defined or * it does not refer to a valid directory, /tmp will be used. * * NOTE: Since the file already exists, the O_EXCL flag must not be used if * the returned filename is opened for usage within an application. It is, * however, the duty of the application calling this function to delete the * file denoted by the generated filename after it is no longer needed. * * INPUTS * char *aBuffer - Array to hold filename * * RESULT * char* - Points to 'aBuffer' if successful, NULL otherwise * * NOTE * MT-NOTE: sge_tmpnam() is MT safe. ******************************************************************************/ char *sge_tmpnam(char *aBuffer, dstring *error_message) { dstring s = DSTRING_INIT; DENTER(TOP_LAYER, "sge_tmpnam"); if (aBuffer == NULL) { sge_dstring_sprintf(error_message, MSG_TMPNAM_GOT_NULL_PARAMETER); DEXIT; return NULL; } if (elect_path(&s) < 0) { sge_dstring_sprintf(error_message, MSG_TMPNAM_CANNOT_GET_TMP_PATH); sge_dstring_free(&s); DEXIT; return NULL; } if ((sge_dstring_get_string(&s))[sge_dstring_strlen(&s)-1] != '/') { sge_dstring_append_char(&s, '/'); } if (spawn_file(&s, error_message) < 0) { sge_dstring_free(&s); DEXIT; return NULL; } sge_strlcpy(aBuffer, sge_dstring_get_string(&s), SGE_PATH_MAX); sge_dstring_free(&s); DPRINTF(("sge_tmpnam: returning %s\n", aBuffer)); DEXIT; return aBuffer; }
void sge_signaler_initialize(sge_gdi_ctx_class_t *ctx) { cl_thread_settings_t* dummy_thread_p = NULL; dstring thread_name = DSTRING_INIT; DENTER(TOP_LAYER, "sge_signaler_initialize"); sge_dstring_sprintf(&thread_name, "%s%03d", threadnames[SIGNALER_THREAD], 0); cl_thread_list_setup(&(Main_Control.signal_thread_pool), "signal thread pool"); cl_thread_list_create_thread(Main_Control.signal_thread_pool, &dummy_thread_p, cl_com_get_log_list(), sge_dstring_get_string(&thread_name), 0, sge_signaler_main, NULL, NULL, CL_TT_SIGNALER); sge_dstring_free(&thread_name); DRETURN_VOID; }
/****** spool/berkeleydb/bdb_get_dbname() ************************************** * NAME * bdb_get_dbname() -- get a meaningfull database name * * SYNOPSIS * const char * * bdb_get_dbname(bdb_info info, dstring *buffer) * * FUNCTION * Return a meaningfull name for a database connection. * It contains the server name (in case of RPC mechanism) and the database * path. * A dstring buffer has to be provided by the caller. * * INPUTS * bdb_info info - the database object * dstring *buffer - buffer to hold the database name * * RESULT * const char * - the database name * * NOTES * MT-NOTE: bdb_get_dbname() is MT safe *******************************************************************************/ const char * bdb_get_dbname(bdb_info info, dstring *buffer) { const char *ret; const char *server = bdb_get_server(info); const char *path = bdb_get_path(info); if (path == NULL) { ret = sge_dstring_copy_string(buffer, MSG_BERKELEY_DBNOTINITIALIZED); } else if (server == NULL) { ret = sge_dstring_copy_string(buffer, path); } else { ret = sge_dstring_sprintf(buffer, "%s:%s", server, path); } return ret; }
void sge_event_master_initialize(sge_gdi_ctx_class_t *ctx) { cl_thread_settings_t* dummy_thread_p = NULL; dstring thread_name = DSTRING_INIT; DENTER(TOP_LAYER, "sge_event_master_initialize"); DPRINTF(("event master functionality has been initialized\n")); sge_dstring_sprintf(&thread_name, "%s%03d", threadnames[DELIVERER_THREAD], 0); cl_thread_list_setup(&(Main_Control.event_master_thread_pool), "event master thread pool"); cl_thread_list_create_thread(Main_Control.event_master_thread_pool, &dummy_thread_p, cl_com_get_log_list(), sge_dstring_get_string(&thread_name), 0, sge_event_master_main, NULL, NULL, CL_TT_DELIVERER); sge_dstring_free(&thread_name); DRETURN_VOID; }
/****** uti/dstring/sge_dstring_ulong_to_binstring() ************************** * NAME * sge_dstring_ulong_to_binstring() -- convert ulong into bin-string * * SYNOPSIS * const char* * sge_dstring_ulong_to_binstring(dstring *sb, u_long32 number) * * FUNCTION * Convert ulong into bin-strin * * INPUTS * dstring *sb - dstring * u_long32 number - 32 bit ulong value * * RESULT * const char* - pointer to dstrings internal buffer *******************************************************************************/ const char *sge_dstring_ulong_to_binstring(dstring *sb, u_long32 number) { char buffer[33] = " "; int i = 31; while (number > 0) { if ((number % 2) > 0) { buffer[i] = '1'; } else { buffer[i] = '0'; } i--; number /= 2; } sge_strip_blanks(buffer); sge_dstring_sprintf(sb, buffer); return sge_dstring_get_string(sb); }
static void test_dstring_performance(dstring *ds, int max, const char *data) { int i; struct timeval before; struct timeval after; double time; gettimeofday(&before, NULL); for (i = 0; i < max; i++) { sge_dstring_sprintf(ds, "%s", data); } gettimeofday(&after, NULL); time = after.tv_usec - before.tv_usec; time = after.tv_sec - before.tv_sec + (time/1000000); printf("%d sge_dstring_sprintf took %.2fs\n", max, time); }
static void test_dstring_performance_dynamic(int max, const char *data) { int i; struct timeval before; struct timeval after; double time; gettimeofday(&before, NULL); for (i = 0; i < max; i++) { dstring ds = DSTRING_INIT; sge_dstring_sprintf(&ds, "%s/%s", data, data); sge_dstring_free(&ds); } gettimeofday(&after, NULL); time = after.tv_usec - before.tv_usec; time = after.tv_sec - before.tv_sec + (time/1000000); printf("%d dstring creations took %.2fs\n", max, time); }
static void test_dstring_performance_static(int max, const char *data) { int i; struct timeval before; struct timeval after; double time; gettimeofday(&before, NULL); for (i = 0; i < max; i++) { dstring ds; char ds_buffer[MAX_STRING_SIZE]; sge_dstring_init(&ds, ds_buffer, sizeof(ds_buffer)); sge_dstring_sprintf(&ds, "%s/%s", data, data); } gettimeofday(&after, NULL); time = after.tv_usec - before.tv_usec; time = after.tv_sec - before.tv_sec + (time/1000000); printf("%d static dstring creations took %.2fs\n", max, time); }
/****** uti/spool/sge_get_active_job_file_path() ******************************** * NAME * sge_get_active_job_file_path() -- Create paths in active_jobs dir * * SYNOPSIS * const char* sge_get_active_job_file_path(dstring *buffer, * u_long32 job_id, u_long32 ja_task_id, const char *pe_task_id, * const char *filename) * * FUNCTION * Creates paths in the execd's active_jobs directory. * Both directory and file paths can be created. * The result is placed in a buffer provided by the caller. * * WARNING: Do only use in shepherd and execution daemon! * * INPUTS * dstring *buffer - buffer to hold the generated path * u_long32 job_id - job id * u_long32 ja_task_id - array task id * const char *pe_task_id - optional pe task id * const char *filename - optional file name * * RESULT * const char* - pointer to the string buffer on success, else NULL * * EXAMPLE * To create the relative path to a jobs/tasks environment file, the * following call would be used: * * char buffer[SGE_PATH_MAX] * sge_get_active_job_file_path(buffer, SGE_PATH_MAX, * job_id, ja_task_id, pe_task_id, * "environment"); * * * NOTES * JG: TODO: The function might be converted to or might use a more * general path creating function (utilib). * * SEE ALSO * execd/sge_make_ja_task_active_dir() * execd/sge_make_pe_task_active_dir() *******************************************************************************/ const char *sge_get_active_job_file_path(dstring *buffer, u_long32 job_id, u_long32 ja_task_id, const char *pe_task_id, const char *filename) { DENTER(TOP_LAYER, "sge_get_active_job_file_path"); if (buffer == NULL) { DRETURN(NULL); } sge_dstring_sprintf(buffer, "%s/"sge_u32"."sge_u32, ACTIVE_DIR, job_id, ja_task_id); if (pe_task_id != NULL) { sge_dstring_append_char(buffer, '/'); sge_dstring_append(buffer, pe_task_id); } if (filename != NULL) { sge_dstring_append_char(buffer, '/'); sge_dstring_append(buffer, filename); } DRETURN(sge_dstring_get_string(buffer)); }
static void qevent_parse_command_line(int argc, char **argv, qevent_options *option_struct) { DENTER(TOP_LAYER, "qevent_parse_command_line"); option_struct->help_option = 0; option_struct->testsuite_option = 0; option_struct->subscribe_option = 0; option_struct->trigger_option_count =0; while (*(++argv)) { if (!strcmp("-h", *argv) || !strcmp("-help", *argv)) { option_struct->help_option = 1; continue; } if (!strcmp("-ts", *argv) || !strcmp("-testsuite", *argv)) { option_struct->testsuite_option = 1; continue; } if (!strcmp("-sm", *argv) || !strcmp("-subscribe", *argv)) { option_struct->subscribe_option = 1; continue; } if (!strcmp("-trigger", *argv)) { int ok = 0; if (option_struct->trigger_option_count >= MAX_TRIGGER_SCRIPTS ) { sge_dstring_sprintf(option_struct->error_message, "option \"-trigger\": only "sge_U32CFormat" trigger arguments supported\n", sge_u32c(MAX_TRIGGER_SCRIPTS) ); break; } ++argv; if (*argv) { /* get EVENT argument */ if (strcmp(qevent_get_event_name(QEVENT_JB_END),*argv) == 0) { ok = 1; (option_struct->trigger_option_events)[option_struct->trigger_option_count] = QEVENT_JB_END; } if (strcmp(qevent_get_event_name(QEVENT_JB_TASK_END),*argv) == 0) { ok = 1; (option_struct->trigger_option_events)[option_struct->trigger_option_count] = QEVENT_JB_TASK_END; } if (!ok) { sge_dstring_append(option_struct->error_message,"option \"-trigger\": undefined EVENT type\n"); break; } } else { sge_dstring_append(option_struct->error_message,"option \"-trigger\": found no EVENT argument\n"); break; } ++argv; if (*argv) { /* get SCRIPT argument */ /* check for SCRIPT file */ if (!sge_is_file(*argv)) { sge_dstring_sprintf(option_struct->error_message, "option \"-trigger\": SCRIPT file %s not found\n", (*argv)); break; } /* is file executable ? */ if (!sge_is_executable(*argv)) { sge_dstring_sprintf(option_struct->error_message, "option \"-trigger\": SCRIPT file %s not executable\n", (*argv)); break; } (option_struct->trigger_option_scripts)[option_struct->trigger_option_count] = *argv; (option_struct->trigger_option_count)++; } else { sge_dstring_append(option_struct->error_message,"option \"-trigger\": found no SCRIPT argument\n"); break; } continue; } /* unkown option */ if ( *argv[0] == '-' ) { sge_dstring_append(option_struct->error_message,"unkown option: "); sge_dstring_append(option_struct->error_message,*argv); sge_dstring_append(option_struct->error_message,"\n"); } else { sge_dstring_append(option_struct->error_message,"unkown argument: "); sge_dstring_append(option_struct->error_message,*argv); sge_dstring_append(option_struct->error_message,"\n"); } } DEXIT; }
/****** sge_binding_hlp/binding_explicit_has_correct_syntax() ********************* * NAME * binding_explicit_has_correct_syntax() -- Check if parameter has correct syntax. * * SYNOPSIS * bool binding_explicit_has_correct_syntax(const char* parameter) * * FUNCTION * This function checks if the given string is a valid argument for the * -binding parameter which provides a list of socket, cores which have * to be selected explicitly. * * The accepted syntax is: "explicit:[1-9][0-9]*,[1-9][0-9]*(:[1-9][0-9]*,[1-9][0-9]*)*" * * This is used from parse_qsub.c. * * INPUTS * const char* parameter - A string with the parameter. * * RESULT * bool - True if the parameter has the expected syntax. * * NOTES * MT-NOTE: binding_explicit_has_correct_syntax() is not MT safe * *******************************************************************************/ bool binding_explicit_has_correct_syntax(const char* parameter, dstring* error) { int amount; /* check if the head is correct */ if (strstr(parameter, "explicit:") == NULL) { sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_NOTFOUND); return false; } if (sge_strtok(parameter, ":") != NULL) { char* socket = NULL; char* core = NULL; /* first socket,core is mandatory */ if ((socket = sge_strtok(NULL, ",")) == NULL) { /* we have no first socket number */ sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_NOPAIR); return false; } /* check if <socket> begins with a digit */ if (!is_digit(socket, ',')) { sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_FIRSTSOCKNONUMBER); return false; } /* check for core */ if ((core = sge_strtok(NULL, ":")) == NULL) { /* we have no first core number */ sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_MISSINGFIRSTCORE); return false; } /* check if <core> begins with a digit */ if (!is_digit(core, ':')) { sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_FIRSTCORENONUMBER); return false; } do { /* get socket number */ if ((socket = sge_strtok(NULL, ",")) != NULL) { /* check if <socket> begins with a digit */ if (!is_digit(socket, ',')) { sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_SOCKNONUMBER); return false; } /* we have a socket therefore we need a core number */ if ((core = sge_strtok(NULL, ":")) == NULL) { /* no core found */ sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_NOCOREFORSOCKET); return false; } /* check if <core> is a number */ if (!is_digit(core, ':')) { sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_COREISNONUMBER); return false; } } /* end if <socket> */ } while (socket != NULL); /* we try to continue with the next socket if possible */ } else { /* this should not be reachable because of the pre-check */ return false; } /* check if there are <socket,core> pairs requested multiple times */ amount = get_explicit_amount(parameter, true); if (check_explicit_binding_string(parameter, amount, true) == false) { sge_dstring_sprintf(error, MSG_SYN_EXPLICIT_PAIRSNOTUNIQUE); return false; } return true; }
/****** sge_binding_hlp/parse_binding_parameter_string() *********************** * NAME * parse_binding_parameter_string() -- Parses binding parameter string. * * SYNOPSIS * bool parse_binding_parameter_string(const char* parameter, u_long32* * type, dstring* strategy, int* amount, int* stepsize, int* firstsocket, * int* firstcore, dstring* socketcorelist, dstring* error) * * FUNCTION * Parses binding parameter string and returns the values of the parameter. * Please check output values in dependency of the strategy string. * * INPUTS * const char* parameter - binding parameter string * * OUTPUT * u_long32* type - type of binding (pe = 0| env = 1|set = 2) * dstring* strategy - binding strategy string * int* amount - amount of cores to bind to * int* stepsize - step size between cores (or -1) * int* firstsocket - first socket to use (or -1) * int* firstcore - first core to use (on "first socket") (or -1) * dstring* socketcorelist - list of socket,core pairs with prefix explicit or NULL * dstring* error - error as string in case of return false * * RESULT * bool - true in case parsing was successful false in case of errors * * NOTES * MT-NOTE: parse_binding_parameter_string() is MT safe * *******************************************************************************/ bool parse_binding_parameter_string(const char* parameter, binding_type_t* type, dstring* strategy, int* amount, int* stepsize, int* firstsocket, int* firstcore, dstring* socketcorelist, dstring* error) { bool retval = true; if (parameter == NULL) { sge_dstring_sprintf(error, "input parameter was NULL"); return false; } /* check the type [pe|env|set] (set is default) */ if (strstr(parameter, "pe ") != NULL) { *type = BINDING_TYPE_PE; } else if (strstr(parameter, "env ") != NULL) { *type = BINDING_TYPE_ENV; } else { *type = BINDING_TYPE_SET; } if (strstr(parameter, "linear") != NULL) { *amount = binding_linear_parse_amount(parameter); if (*amount < 0) { /* couldn't parse amount of cores */ sge_dstring_sprintf(error, "couldn't parse amount (linear)"); return false; } *firstsocket = binding_linear_parse_socket_offset(parameter); if (*firstsocket == -2) { sge_dstring_sprintf(error, "couldn't parse socket number (linear)"); return false; } if (*firstsocket < 0) { /* no socket number given, hence we don't scan for the core number */ *firstcore = *firstsocket; } else { *firstcore = binding_linear_parse_core_offset(parameter); if (*firstcore < 0) { /* there was an error during parsing the core number */ sge_dstring_sprintf(error, "couldn't parse core number (linear)"); return false; } } if (*firstsocket < 0 && *firstcore < 0) { /* couldn't find start <socket,core> -> must be determined automatically */ sge_dstring_sprintf(strategy, "linear_automatic"); /* this might be an error on shepherd side only */ *firstsocket = -1; *firstcore = -1; } else { sge_dstring_sprintf(strategy, "linear"); } /* set step size to dummy */ *stepsize = -1; } else if (strstr(parameter, "striding") != NULL) { *amount = binding_striding_parse_amount(parameter); if (*amount < 0) { /* couldn't parse amount of cores */ sge_dstring_sprintf(error, "couldn't parse amount (striding)"); return false; } *stepsize = binding_striding_parse_step_size(parameter); if (*stepsize < 0) { /* no given stepsize does lead to stepsize 0 which will be extended on the execution host to <amount of cores per socket>. When using a start socket,core the stepsize 0 has to be included (binding striding:<amount>:0:<socket>,<core>.*/ /* *stepsize = 0; */ sge_dstring_sprintf(error, "couldn't parse stepsize (striding)"); return false; } *firstsocket = binding_striding_parse_first_socket(parameter); if (*firstsocket == -2) { sge_dstring_sprintf(error, "couldn't parse socket number (striding)"); return false; } if (*firstsocket == -1) { *firstcore = -1; } else { /* we need to parse the core number since a socket number is given */ *firstcore = binding_striding_parse_first_core(parameter); if (*firstcore < 0) { sge_dstring_sprintf(error, "couldn't parse core number (striding)"); return false; } } if (*firstsocket < 0 || *firstcore < 0) { sge_dstring_sprintf(strategy, "striding_automatic"); /* this might be an error on shepherd side only */ *firstsocket = -1; *firstcore = -1; } else { sge_dstring_sprintf(strategy, "striding"); } } else if (strstr(parameter, "explicit") != NULL) { if (binding_explicit_has_correct_syntax(parameter, error) == false) { retval = false; } else { if (socketcorelist == NULL) { sge_dstring_sprintf(error, MSG_SYNTAX_DSTRINGBUG); retval = false; } else { char* pos = strstr(parameter, "explicit"); sge_dstring_copy_string(socketcorelist, pos); sge_dstring_sprintf(strategy, "explicit"); pos = NULL; } } } else { /* error: no valid strategy found */ sge_dstring_sprintf(error, "couldn't parse binding parameter (no strategy found)"); retval = false; } return retval; }
bool sge_bootstrap(const char *bootstrap_file, dstring *error_dstring) { bool ret = true; int i = 0; /*const char **/ bootstrap_entry_t name[NUM_BOOTSTRAP] = { {"admin_user", true}, {"default_domain", true}, {"ignore_fqdn", true}, {"spooling_method", true}, {"spooling_lib", true}, {"spooling_params", true}, {"binary_path", true}, {"qmaster_spool_dir", true}, {"security_mode", true}, {"job_spooling", false}, {"listener_threads", false}, {"worker_threads", false}, {"scheduler_threads", false}, {"jvm_threads", false} }; char value[NUM_BOOTSTRAP][1025]; DENTER(TOP_LAYER, "sge_bootstrap"); for (i = 0; i < NUM_BOOTSTRAP; i++) { value[i][0] = '\0'; } /* get filepath of bootstrap file */ if (bootstrap_file == NULL) { if (error_dstring == NULL) { CRITICAL((SGE_EVENT, SFNMAX, MSG_UTI_CANNOTRESOLVEBOOTSTRAPFILE)); } else { sge_dstring_sprintf(error_dstring, "%s", MSG_UTI_CANNOTRESOLVEBOOTSTRAPFILE); } ret = false; /* read bootstrapping information */ } else if (sge_get_confval_array(bootstrap_file, NUM_BOOTSTRAP, NUM_REQ_BOOTSTRAP, name, value, error_dstring)) { ret = false; } else { /* store bootstrapping information */ bootstrap_set_admin_user(value[0]); bootstrap_set_default_domain(value[1]); { u_long32 uval; parse_ulong_val(NULL, &uval, TYPE_BOO, value[2], NULL, 0); bootstrap_set_ignore_fqdn(uval ? true : false); } bootstrap_set_spooling_method(value[3]); bootstrap_set_spooling_lib(value[4]); bootstrap_set_spooling_params(value[5]); bootstrap_set_binary_path(value[6]); bootstrap_set_qmaster_spool_dir(value[7]); bootstrap_set_security_mode(value[8]); if (strcmp(value[9], "")) { u_long32 uval = 0; parse_ulong_val(NULL, &uval, TYPE_BOO, value[9], NULL, 0); bootstrap_set_job_spooling(uval ? true : false); } else { bootstrap_set_job_spooling(true); } { u_long32 uval = 0; parse_ulong_val(NULL, &uval, TYPE_INT, value[10], NULL, 0); bootstrap_set_listener_thread_count(uval); } { u_long32 uval = 0; parse_ulong_val(NULL, &uval, TYPE_INT, value[11], NULL, 0); bootstrap_set_worker_thread_count(uval); } { u_long32 uval = 0; parse_ulong_val(NULL, &uval, TYPE_INT, value[12], NULL, 0); bootstrap_set_scheduler_thread_count(uval); } { u_long32 uval = 0; parse_ulong_val(NULL, &uval, TYPE_INT, value[13], NULL, 0); bootstrap_set_jvm_thread_count(uval); } DPRINTF(("admin_user >%s<\n", bootstrap_get_admin_user())); DPRINTF(("default_domain >%s<\n", bootstrap_get_default_domain())); DPRINTF(("ignore_fqdn >%s<\n", bootstrap_get_ignore_fqdn() ? "true" : "false")); DPRINTF(("spooling_method >%s<\n", bootstrap_get_spooling_method())); DPRINTF(("spooling_lib >%s<\n", bootstrap_get_spooling_lib())); DPRINTF(("spooling_params >%s<\n", bootstrap_get_spooling_params())); DPRINTF(("binary_path >%s<\n", bootstrap_get_binary_path())); DPRINTF(("qmaster_spool_dir >%s<\n", bootstrap_get_qmaster_spool_dir())); DPRINTF(("security_mode >%s<\n", bootstrap_get_security_mode())); DPRINTF(("job_spooling >%s<\n", bootstrap_get_job_spooling() ? "true":"false")); DPRINTF(("listener_threads >%d<\n", bootstrap_get_listener_thread_count())); DPRINTF(("worker_threads >%d<\n", bootstrap_get_worker_thread_count())); DPRINTF(("scheduler_threads >%d<\n", bootstrap_get_scheduler_thread_count())); DPRINTF(("jvm_threads >%d<\n", bootstrap_get_jvm_thread_count())); } DEXIT; return ret; }
/****** qmaster/threads/sge_scheduler_initialize() *************************** * NAME * sge_scheduler_initialize() -- setup and start the scheduler thread * * SYNOPSIS * void sge_scheduler_initialize(sge_gdi_ctx_class_t *ctx) * * FUNCTION * A call to this function initializes the scheduler thread if it is * not already running. * * The first call to this function (during qmaster qstart) starts * the scheduler thread only if it is enabled in the bootstrap file. * Otherwise the scheduler will not be started. * * Each subsequent call (triggered from GDI) will definitely start * the scheduler thread if it is not running. * * Main routine for the created thread is sge_scheduler_main(). * * 'Master_Scheduler' is accessed by this function. * * INPUTS * sge_gdi_ctx_class_t *ctx - context object * lList **answer_list - answer list * * RESULT * void - None * * NOTES * MT-NOTE: sge_scheduler_initialize() is MT safe * * SEE ALSO * qmaster/threads/sge_scheduler_initialize() * qmaster/threads/sge_scheduler_cleanup_thread() * qmaster/threads/sge_scheduler_terminate() * qmaster/threads/sge_scheduler_main() *******************************************************************************/ void sge_scheduler_initialize(sge_gdi_ctx_class_t *ctx, lList **answer_list) { DENTER(TOP_LAYER, "sge_scheduler_initialize"); /* initialize debugging instrumentation */ { char *debug = getenv("SGE_TEST_DELAY_SCHEDULING"); if (debug != NULL) { SGE_TEST_DELAY_SCHEDULING = atoi(debug); } } sge_mutex_lock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); if (Master_Scheduler.is_running == false) { bool start_thread = true; /* * when this function is called the first time we will use the setting from * the bootstrap file to identify if the scheduler should be started or not * otherwise we have to start the thread due to a manual request through GDI. * There is no option. We have to start it. */ if (Master_Scheduler.use_bootstrap == true) { start_thread = ((ctx->get_scheduler_thread_count(ctx) > 0) ? true : false); Master_Scheduler.use_bootstrap = false; } if (start_thread == true) { cl_thread_settings_t* dummy_thread_p = NULL; dstring thread_name = DSTRING_INIT; /* * initialize the thread pool */ cl_thread_list_setup(&(Main_Control.scheduler_thread_pool), "thread pool"); /* * prepare a unique scheduler thread name for each instance of an scheduler */ sge_dstring_sprintf(&thread_name, "%s%03d", threadnames[SCHEDD_THREAD], Master_Scheduler.thread_id); /* * start the scheduler */ cl_thread_list_create_thread(Main_Control.scheduler_thread_pool, &dummy_thread_p, cl_com_get_log_list(), sge_dstring_get_string(&thread_name), Master_Scheduler.thread_id, sge_scheduler_main, NULL, NULL, CL_TT_SCHEDULER); sge_dstring_free(&thread_name); /* * Increase the thread id so that the next instance of a scheduler will have a * different name and flag that scheduler is running */ Master_Scheduler.thread_id++; Master_Scheduler.is_running = true; INFO((SGE_EVENT, MSG_THREAD_XHASSTARTED_S, threadnames[SCHEDD_THREAD])); answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_INFO); } else { INFO((SGE_EVENT, MSG_THREAD_XSTARTDISABLED_S, threadnames[SCHEDD_THREAD])); answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_INFO); } } else { ERROR((SGE_EVENT, MSG_THREAD_XISRUNNING_S, threadnames[SCHEDD_THREAD])); answer_list_add(answer_list, SGE_EVENT, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR); } sge_mutex_unlock("master scheduler struct", SGE_FUNC, __LINE__, &(Master_Scheduler.mutex)); DRETURN_VOID; }
/****** run_ijs_server() ******************************************************* * NAME * run_ijs_server() -- The servers main loop * * SYNOPSIS * int run_ijs_server(u_long32 job_id, int nostdin, int noshell, * int is_rsh, int is_qlogin, int force_pty, * int *p_exit_status) * * FUNCTION * The main loop of the commlib server, handling the data transfer from * and to the client. * * INPUTS * COMM_HANDLE *handle - Handle of the COMM server * u_long32 job_id - SGE job id of this job * int nostdin - The "-nostdin" switch * int noshell - The "-noshell" switch * int is_rsh - Is it a qrsh with commandline? * int is_qlogin - Is it a qlogin or qrsh without commandline? * int suspend_remote - suspend_remote switch of qrsh * int force_pty - The user forced use of pty by the "-pty yes" switch * * OUTPUTS * int *p_exit_status - The exit status of qrsh_starter in case of * "qrsh <command>" or the exit status of the shell in * case of "qrsh <no command>"/"qlogin". * If the job was signalled, the exit code is 128+signal. * * RESULT * int - 0: Ok. * 1: Invalid parameter * 2: Log list not initialized * 3: Error setting terminal mode * 4: Can't create tty_to_commlib thread * 5: Can't create commlib_to_tty thread * 6: Error shutting down commlib connection * 7: Error resetting terminal mode * * NOTES * MT-NOTE: run_ijs_server is not MT-safe *******************************************************************************/ int run_ijs_server(COMM_HANDLE *handle, const char *remote_host, u_long32 job_id, int nostdin, int noshell, int is_rsh, int is_qlogin, ternary_t force_pty, ternary_t suspend_remote, int *p_exit_status, dstring *p_err_msg) { int ret = 0, ret_val = 0; THREAD_HANDLE *pthread_tty_to_commlib = NULL; THREAD_HANDLE *pthread_commlib_to_tty = NULL; THREAD_LIB_HANDLE *thread_lib_handle = NULL; cl_raw_list_t *cl_com_log_list = NULL; DENTER(TOP_LAYER, "run_ijs_server"); if (handle == NULL || p_err_msg == NULL || p_exit_status == NULL || remote_host == NULL) { return 1; } g_comm_handle = handle; g_hostname = strdup(remote_host); cl_com_log_list = cl_com_get_log_list(); if (cl_com_log_list == NULL) { return 2; } g_nostdin = nostdin; g_noshell = noshell; g_pid = getpid(); g_is_rsh = is_rsh; if (suspend_remote == UNSET || suspend_remote == NO) { g_suspend_remote = 0; } else { g_suspend_remote = 1; } /* * qrsh without command and qlogin both have is_rsh == 0 and is_qlogin == 1 * qrsh with command and qsh don't need to set terminal mode. * If the user requested a pty we also have to set terminal mode. * But only if stdout is still connected to a tty and not redirected * to a file or a pipe. */ if (isatty(STDOUT_FILENO) == 1 && ((force_pty == UNSET && is_rsh == 0 && is_qlogin == 1) || force_pty == YES)) { /* * Set this terminal to raw mode, just output everything, don't interpret * it. Let the pty on the client side interpret the characters. */ ret = terminal_enter_raw_mode(); if (ret != 0) { sge_dstring_sprintf(p_err_msg, "can't set terminal to raw mode: %s (%d)", strerror(ret), ret); return 3; } else { g_raw_mode_state = 1; } } /* * Setup thread list and create two worker threads */ thread_init_lib(&thread_lib_handle); /* * From here on, we have to cleanup the list in case of errors, this is * why we "goto cleanup" in case of error. */ DPRINTF(("creating worker threads\n")); DPRINTF(("creating tty_to_commlib thread\n")); ret = create_thread(thread_lib_handle, &pthread_tty_to_commlib, cl_com_log_list, "tty_to_commlib thread", 1, tty_to_commlib); if (ret != CL_RETVAL_OK) { sge_dstring_sprintf(p_err_msg, "can't create tty_to_commlib thread: %s", cl_get_error_text(ret)); ret_val = 4; goto cleanup; } DPRINTF(("creating commlib_to_tty thread\n")); ret = create_thread(thread_lib_handle, &pthread_commlib_to_tty, cl_com_log_list, "commlib_to_tty thread", 1, commlib_to_tty); if (ret != CL_RETVAL_OK) { sge_dstring_sprintf(p_err_msg, "can't create commlib_to_tty thread: %s", cl_get_error_text(ret)); ret_val = 5; goto cleanup; } /* * From here on, the two worker threads are doing all the work. * This main thread is just waiting until the client closes the * connection to us, which causes the commlib_to_tty thread to * exit. Then it closes the tty_to_commlib thread, too, and * cleans up everything. */ DPRINTF(("waiting for end of commlib_to_tty thread\n")); thread_join(pthread_commlib_to_tty); DPRINTF(("shutting down tty_to_commlib thread\n")); thread_shutdown(pthread_tty_to_commlib); /* * Close stdin to awake the tty_to_commlib-thread from the select() call. * thread_shutdown() doesn't work on all architectures. */ close(STDIN_FILENO); DPRINTF(("waiting for end of tty_to_commlib thread\n")); thread_join(pthread_tty_to_commlib); cleanup: /* * Set our terminal back to 'unraw' mode. Should be done automatically * by OS on process end, but we want to be sure. */ ret = terminal_leave_raw_mode(); DPRINTF(("terminal_leave_raw_mode() returned %s (%d)\n", strerror(ret), ret)); if (ret != 0) { sge_dstring_sprintf(p_err_msg, "error resetting terminal mode: %s (%d)", strerror(ret)); ret_val = 7; } *p_exit_status = g_exit_status; thread_cleanup_lib(&thread_lib_handle); DRETURN(ret_val); }
static bool check_all(dstring *sb) { bool ret = true; int i; /* sge_dstring_append */ printf("\nchecking sge_dstring_append\n"); sge_dstring_append(NULL, NULL); sge_dstring_append(sb, NULL); check_dstring(sb); sge_dstring_append(sb, "blah"); check_dstring(sb); sge_dstring_clear(sb); sge_dstring_append(sb, "too long string to fit into a static string buffer"); check_dstring(sb); sge_dstring_clear(sb); sge_dstring_append(sb, "long string that requires multiple chunks ....... "); check_dstring(sb); for (i = 0; i < 20; i++) { sge_dstring_append(sb, "long string that requires multiple chunks ....... "); } check_dstring(sb); /* sge_dstring_append_dstring */ printf("\nchecking sge_dstring_append_dstring\n"); sge_dstring_clear(sb); sge_dstring_append_dstring(NULL, NULL); { dstring second = DSTRING_INIT; sge_dstring_append(&second, "dstring"); sge_dstring_append_dstring(NULL, &second); sge_dstring_append_dstring(sb, NULL); sge_dstring_append_dstring(sb, &second); check_dstring(sb); sge_dstring_free(&second); } /* sge_dstring_append_char */ printf("\nchecking sge_dstring_append_char\n"); sge_dstring_clear(sb); sge_dstring_append_char(NULL, 'a'); sge_dstring_append_char(sb, '\0'); check_dstring(sb); sge_dstring_append_char(sb, 'a'); check_dstring(sb); sge_dstring_append_char(sb, 'b'); check_dstring(sb); /* sge_dstring_sprintf */ printf("\nchecking sge_dstring_sprintf\n"); sge_dstring_sprintf(NULL, "test %s", "string"); sge_dstring_sprintf(sb, NULL); sge_dstring_sprintf(sb, "test %s", "string"); check_dstring(sb); #if 0 /* does not build on irix */ /* sge_dstring_vsprintf */ printf("\nchecking sge_dstring_vsprintf\n"); { const char *args[] = { "string", NULL }; sge_dstring_clear(sb); sge_dstring_vsprintf(NULL, "test %s", args); sge_dstring_vsprintf(sb, NULL, args); sge_dstring_vsprintf(sb, "test %s", args); check_dstring(sb); } #endif /* sge_dstring_sprintf_append */ printf("\nchecking sge_dstring_sprintf_append\n"); sge_dstring_clear(sb); sge_dstring_sprintf_append(NULL, "test %s", "string"); sge_dstring_sprintf_append(sb, NULL); sge_dstring_sprintf_append(sb, "test %s", "string"); sge_dstring_sprintf_append(sb, " appended test %s", "string"); check_dstring(sb); /* sge_dstring_clear */ printf("\nchecking sge_dstring_clear\n"); sge_dstring_clear(NULL); sge_dstring_clear(sb); check_dstring(sb); /* sge_dstring_free */ printf("\nchecking sge_dstring_free\n"); sge_dstring_free(NULL); sge_dstring_free(sb); check_dstring(sb); /* sge_dstring_get_string */ printf("\nchecking sge_dstring_get_string\n"); sge_dstring_clear(sb); sge_dstring_append(sb, "test string"); { const char *result; result = sge_dstring_get_string(NULL); printf("sge_dstring_get_string(NULL) = %s\n", result == NULL ? "NULL" : result); result = sge_dstring_get_string(sb); printf("sge_dstring_get_string(sb) = %s\n", result == NULL ? "NULL" : result); } /* sge_dstring_copy_string */ printf("\nchecking sge_dstring_copy_string\n"); sge_dstring_copy_string(NULL, NULL); sge_dstring_copy_string(sb, NULL); sge_dstring_copy_string(NULL, "new test string"); sge_dstring_copy_string(sb, "new test string"); check_dstring(sb); /* sge_dstring_copy_dstring * check only NULL pointer behaviour, it just calls sge_dstring_copy_string */ printf("\nchecking sge_dstring_copy_dstring\n"); sge_dstring_copy_dstring(NULL, NULL); sge_dstring_copy_dstring(sb, NULL); check_dstring(sb); /* sge_dstring_strlen */ printf("\nchecking sge_dstring_strlen\n"); { int len; sge_dstring_copy_string(sb, "test string"); len = sge_dstring_strlen(NULL); printf("sge_dstring_strlen(NULL) = %d\n", len); len = sge_dstring_strlen(sb); printf("sge_dstring_strlen(sb) = %d\n", len); } /* sge_dstring_remaining */ printf("\nchecking sge_dstring_remaining\n"); { int len; sge_dstring_copy_string(sb, "test string"); len = sge_dstring_remaining(NULL); printf("sge_dstring_remaining(NULL) = %d\n", len); len = sge_dstring_remaining(sb); printf("sge_dstring_remaining(sb) = %d\n", len); } return ret; }