/* when a PMC daemon is started, it first checks if there's already a daemon running on the network with the same nodekey, if yes, the newly started daemon automaticly runs in backup mode until demanded to switch to primary mode. */ bool setup_running_state() { __uint items; NODE_KEY nodeKey; char buffer[8192]; string dirname; *buffer = 0; /* running-state check must be done in backup mode. */ set_power_state(PWR_BACKUP); host_to_node(&g_ThisNode->key, &nodeKey); utils_trace("Finding primary site....\n"); items = discover_configfiles(&nodeKey, buffer, sizeof(buffer), 2000); if(!items){ utils_trace("No primary site found, starting as primary.\n"); set_power_state(PWR_RUNNING); }else{ if(!g_bAllowBackup){ utils_error( "Primary site unexpected, " "use '-2' command line option to force start as backup.\n" ); return __false; } utils_trace("Primary site found, server will be started in backup mode.\n"); #if 0 __uint i, filesize; char *item, *filebuf; FILE *fp; utils_trace("Primary site found, downloading configurations....\n"); item = buffer; dirname = get_working_dir(); for(i=0; i<items && *item; i++){ utils_trace("Downloading file (%d of %d) %s....\n", i+1, items, item); if(!download_file(&nodeKey, item, &filebuf, &filesize)){ utils_error("Unable to download '%s'\n", item); return false; } fp = fopen((dirname + "/" + item).data(), "wb"); if(!fp){ utils_error("Unable to write to '%s'\n", item); proxy_release_data(filebuf); return false; } fwrite(filebuf, 1, filesize, fp); fclose(fp); proxy_release_data(filebuf); item += strlen(item) + 1; rtk_sleep(100); } #endif } return true; }
static int apm_console_blank(int blank) { int error = APM_NOT_ENGAGED; /* silence gcc */ int i; u_short state; static const u_short dev[3] = { 0x100, 0x1FF, 0x101 }; state = blank ? APM_STATE_STANDBY : APM_STATE_READY; for (i = 0; i < ARRAY_SIZE(dev); i++) { error = set_power_state(dev[i], state); if ((error == APM_SUCCESS) || (error == APM_NO_ERROR)) return 1; if (error == APM_NOT_ENGAGED) break; } if (error == APM_NOT_ENGAGED) { static int tried; int eng_error; if (tried++ == 0) { eng_error = apm_engage_power_management(APM_DEVICE_ALL, 1); if (eng_error) { apm_error("set display", error); apm_error("engage interface", eng_error); return 0; } else return apm_console_blank(blank); } } apm_error("set display", error); return 0; }
static int pow_set_power(struct msg *msg) { int state; state = msg->data[0]; set_power_state(state); return 0; }
static void power_thread(void) { int sig, event, state; DPRINTF(("power_thread: start\n")); for (;;) { /* * Wait signals from PM driver. */ exception_wait(&sig); DPRINTF(("power_thread: sig=%d\n", sig)); if (sig == SIGPWR) { /* * Query PM events. */ device_ioctl(pmdev, PMIOC_QUERY_EVENT, &event); DPRINTF(("power_thread: event=%d\n", event)); /* * Do action for current power settings. */ state = PWR_ON; switch (event) { case PME_PWRBTN_PRESS: state = pmact.pwrbtn; break; case PME_LOW_BATTERY: state = pmact.lowbatt; break; case PME_SLPBTN_PRESS: state = pmact.slpbtn; break; case PME_LCD_CLOSE: state = pmact.lcdclose; break; } if (state != PWR_ON) set_power_state(state); } } }
__bool switch_to_backup() { UTILS_TIME t1, t2; __bool ret; time_mark(&t1); utils_trace(">> %s : switching to backup mode ....\n", _texttime().data()); ret = set_power_state(PWR_BACKUP); time_mark(&t2); utils_trace( ">> Mode switch %s , time elapsed is %.3f seconds.\n", ret? "OK" : "FAILED.", time_diff(&t2, &t1) ); return ret; }
static int32_t enable_als(uint32_t enable) { int32_t ret; ret = set_power_state(enable?0:1); if (enable) { if (pStkAlsData->bThreadRunning == 0) { pStkAlsData->als_lux_last = 0; pStkAlsData->bThreadRunning = 1; polling_tsk = kthread_run(polling_function, NULL, "als_polling"); } else WARNING("STK_ALS : thread has running\n"); } else { if (pStkAlsData->bThreadRunning) { pStkAlsData->bThreadRunning = 0; STK_LOCK(0); wait_for_completion(&thread_completion); STK_LOCK(1); polling_tsk = NULL; } } return ret; }
static int set_system_power_state(u_short state) { return set_power_state(APM_DEVICE_ALL, state); }
void handle_system_power_state(PowerState power_state, PowerStateCycle cycle, const std::string& action, const Uuid& system_uuid, std::function<void()> pre_action, std::function<void()> cycle_on_action) { static constexpr auto LOCK_CHECKING_PERIOD = std::chrono::milliseconds(100); /* Check if command successful only for TRIES * PERIOD */ static constexpr auto POWER_STATE_CHECKING_PERIOD = std::chrono::milliseconds(1000); static constexpr unsigned POWER_STATE_CHECKING_TRIES = 120; /* check if system is "locked" by another power_control command. * Mutex cannot be used in purpose of locking: whole manager should be * locked then, so "busy waiting" pattern must be used. */ while (true) { { /* critical section on system */ auto system = get_system_reference(system_uuid); if (!system->is_power_state_being_changed()) { system->set_power_state_being_changed(true); break; } } std::this_thread::sleep_for(LOCK_CHECKING_PERIOD); } ManagementController mc{}; set_connection_data(mc, system_uuid); std::string message{}; bool ipmi_fail{false}; bool is_power_on{}; bool set_state{true}; try { is_power_on = check_current_power_state_is_on(mc); /* check if system is in correct state. The job cannot be done * when task is being started: another task might be running and * power state might be been changed. */ switch (power_state) { case PowerState::ACPI_SOFT_SHUTDOWN: case PowerState::POWER_DOWN: if (!is_power_on) { set_state = false; } break; case PowerState::POWER_UP: if (is_power_on) { set_state = false; } break; case PowerState::POWER_CYCLE: case PowerState::HARD_RESET: if (!is_power_on) { message = "System is OFF."; } break; /* special case for TPM */ case PowerState::LAST: if (cycle == PowerStateCycle::CYCLE) { if (is_power_on) { power_state = PowerState::POWER_CYCLE; } else { power_state = PowerState::POWER_UP; } break; } /* continue in DIAGNOSTIC/UNKNOWN */ case PowerState::DIAGNOSTIC_INTERRUPT: case PowerState::UNKNOWN: default: assert(FAIL("Unreachable code")); message = "Not handled"; set_state = false; break; } if (!set_state) { log_info("compute-agent", "State " << action << " [" << static_cast<unsigned>(power_state) << "] already set for " << mc.get_info()); } else if (message.empty()) { pre_action(); log_info("compute-agent", "Setting state " << action << " [" << static_cast<unsigned>(power_state) << "] for " << mc.get_info()); send_desired_power_state(mc, power_state); /* check if state is being changed properly */ unsigned tries; for (tries = 0; tries < POWER_STATE_CHECKING_TRIES; tries++) { /* wait for potential state change.. */ std::this_thread::sleep_for(POWER_STATE_CHECKING_PERIOD); bool previous_state = is_power_on; try { is_power_on = check_current_power_state_is_on(mc); } catch (const std::runtime_error& e) { log_error("compute-agent", "An error occured while checking current power state: " << e.what()); continue; } /* cycle_on action is done only if got into ON state */ if (is_power_on && (previous_state != is_power_on)) { /* there's no time checking for this function! */ cycle_on_action(); } /* check "stable" target state */ if (((cycle == PowerStateCycle::ON) && is_power_on) || ((cycle == PowerStateCycle::OFF) && (!is_power_on))) { log_info("compute-agent", "Target state for " << action << " is set after " << tries << " for " << mc.get_info()); break; } /* If power state should cycle, wait for "next" target state.. */ if ((cycle == PowerStateCycle::CYCLE) && (is_power_on != previous_state)) { if (power_state != PowerState::POWER_CYCLE) { power_state = (is_power_on) ? PowerState::POWER_DOWN : PowerState::POWER_UP; log_info("compute-agent", "Restoring state " << action << " [" << static_cast<unsigned>(power_state) << "] for " << mc.get_info()); send_desired_power_state(mc, power_state); } /* wait for new state */ cycle = (is_power_on) ? PowerStateCycle::OFF : PowerStateCycle::ON; log_info("compute-agent", "Wait for system is " << (is_power_on ? "OFF" : "ON") << " for " << mc.get_info()); } } if (tries >= POWER_STATE_CHECKING_TRIES) { message = "Power state setting timeout"; } } } catch (ipmi::ResponseError& error) { message = std::string(error.what()) + " [CC=" + std::to_string(unsigned(error.get_completion_code())) + "]"; ipmi_fail = true; } catch (const std::runtime_error& e) { message = std::string(e.what()); ipmi_fail = true; } /* done, set state in the resource, regardless it has succeeded! */ { /* critical section on system */ auto system = get_system_reference(system_uuid); system->set_power_state_being_changed(false); /* set last read power_state in the model */ system->set_power_state(is_power_on ? enums::PowerState::On : enums::PowerState::Off); } if (!message.empty()) { if (ipmi_fail) { THROW(IpmiError, "compute-agent", "Error sending " + action + " for " + mc.get_info() + ": " + message); } else { THROW(InvalidValue, "compute-agent", "Error sending " + action + " for " + mc.get_info() + ": " + message); } } }