/*
	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;
}
Exemple #2
0
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;
}
Exemple #3
0
static int
pow_set_power(struct msg *msg)
{
    int state;

    state = msg->data[0];
    set_power_state(state);
    return 0;
}
Exemple #4
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;
}
Exemple #7
0
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);
        }
    }
}