pwr_tStatus proc_Start ( proc_sProcess *p ) { pwr_tStatus sts = PROC__SUCCESS; char **argv; p->pid = fork(); if (p->pid) { if (p->pid == -1) { errh_Error("Could not start %s, %m\nfile: %s", p->name, errno_GetStatus(), p->file); } else { errh_Info("Started %s, prio: %d, pid: %d\nfile: %s", p->name, p->p_prio, (int)p->pid, p->file); } } else { sts = proc_SetPriority(p->p_prio); if (EVEN(sts)) errh_Warning("%s: error setprio, %m\nfile: %s", p->name, sts, p->file); argv = co_StrToArgv(p->file, p->arg); execvp(p->file, argv); errh_Error("%s: error execvp, %m\nfile: %s", p->name, errno_GetStatus(), p->file); exit(EXIT_FAILURE); } return sts; }
//-------------------------------------------------------------------------------------------------- static void SetPriority ( const char* priorityPtr ///< [IN] Priority to set the process to. If this is NULL the /// default priority will be used. ) { const char* priorityStr = DEFAULT_PRIORITY; if (priorityPtr != NULL) { priorityStr = priorityPtr; } INTERNAL_ERR_IF(proc_SetPriority(priorityStr, 0) != LE_OK, "Could not set the priority level to '%s'.\n", priorityStr); }
int main ( int argc, char *argv[] ) { pwr_tStatus sts; int event; plc_sProcess *pp; uid_t ruid; struct passwd *pwd; /* struct rlimit rlim; int i; */ /* Set core dump file size limit to infinite */ /* rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; sts = setrlimit(RLIMIT_CORE, &rlim); printf("%d\n", sts); i = 1/0; printf("%d\n", i); */ pp = init_process(); qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcInit, qcom_cTmoEternal); init_plc(pp); create_threads(pp); init_threads(pp); /* Once threads has set their priority don't run as root */ #if 0 ruid = getuid(); if (ruid == 0) { pwd = getpwnam("pwrp"); if (pwd != NULL) { setreuid(pwd->pw_uid, pwd->pw_uid); } } else setreuid(ruid, ruid); #endif qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcInitDone); qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcStart, qcom_cTmoEternal); // proc_SetPriority(pp->PlcProcess->Prio); set_values(pp); start_threads(pp); run_threads(pp); time_Uptime(&sts, &pp->PlcProcess->StartTime, NULL); qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcStartDone); #if 0 /* Force the backup to take care initialized backup objects. */ bck_ForceBackup(NULL); #endif errh_SetStatus( PWR__SRUN); qcom_WaitOr(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_terminate | ini_mEvent_oldPlcStop, qcom_cTmoEternal, &event); switch ( event) { case ini_mEvent_terminate: errh_SetStatus( PWR__SRVTERM); stop_threads(pp); clean_all(pp); nmps_delete_lock( &sts); break; case ini_mEvent_oldPlcStop: errh_SetStatus( PWR__SRVTERM); time_Uptime(&sts, &pp->PlcProcess->StopTime, NULL); stop_threads(pp); save_values(pp); qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_oldPlcStopDone); #if defined OS_ELN sts = proc_SetPriority(31); #endif clean_all(pp); break; default: ; } exit(0); }
//-------------------------------------------------------------------------------------------------- le_result_t proc_SetPriority ( const char* priorStr, ///< [IN] Priority level string. pid_t pid ///< [IN] PID of the process to set the priority for. ) { // Declare these varialbes with the default values. struct sched_param priority = {.sched_priority = 0}; int policy = SCHED_OTHER; int niceLevel = MEDIUM_PRIORITY_NICE_LEVEL; if (strcmp(priorStr, "idle") == 0) { policy = SCHED_IDLE; } else if (strcmp(priorStr, "low") == 0) { niceLevel = LOW_PRIORITY_NICE_LEVEL; } else if (strcmp(priorStr, "high") == 0) { niceLevel = HIGH_PRIORITY_NICE_LEVEL; } else if ( (priorStr[0] == 'r') && (priorStr[1] == 't') ) { // Get the realtime level from the characters following "rt". char *endPtr; errno = 0; int level = strtol(&(priorStr[2]), &endPtr, 10); if ( (*endPtr != '\0') || (level < MIN_RT_PRIORITY) || (level > MAX_RT_PRIORITY) ) { LE_WARN("Unrecognized priority level (%s) for process '%d'. Using default priority.", priorStr, pid); } else { policy = SCHED_RR; priority.sched_priority = level; } } else if (strcmp(priorStr, "medium") != 0) { LE_WARN("Unrecognized priority level for process '%d'. Using default priority.", pid); } // Set the policy and priority. if (sched_setscheduler(pid, policy, &priority) == -1) { LE_ERROR("Could not set the scheduling policy. %m."); return LE_FAULT; } // Set the nice level. errno = 0; if (setpriority(PRIO_PROCESS, pid, niceLevel) == -1) { LE_ERROR("Could not set the nice level. %m."); return LE_FAULT; } return LE_OK; } //-------------------------------------------------------------------------------------------------- /** * Sets the scheduling policy, priority and/or nice level for the specified process based on the * process' configuration settings in the config tree. * * @note This function kills the specified process if there is an error. */ //-------------------------------------------------------------------------------------------------- static void SetSchedulingPriority ( proc_Ref_t procRef ///< [IN] The process to set the priority for. ) { // Read the priority setting from the config tree. le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot); char priorStr[LIMIT_MAX_PRIORITY_NAME_BYTES]; if (le_cfg_GetString(procCfg, CFG_NODE_PRIORITY, priorStr, sizeof(priorStr), "medium") != LE_OK) { LE_CRIT("Priority string for process %s is too long. Using default priority.", procRef->name); LE_ASSERT(le_utf8_Copy(priorStr, "medium", sizeof(priorStr), NULL) == LE_OK); } le_cfg_CancelTxn(procCfg); if (proc_SetPriority(priorStr, procRef->pid) != LE_OK) { kill_Hard(procRef->pid); } }