Beispiel #1
0
static void wd_resource_failed (struct cs_fsm* fsm, int32_t event, void * data)
{
	struct resource* ref = (struct resource*)data;

	if (ref->check_timer) {
		api->timer_delete(ref->check_timer);
		ref->check_timer = NULL;
	}

	log_printf (LOGSYS_LEVEL_CRIT, "%s resource \"%s\" failed!",
		ref->recovery, (char*)ref->name);
	if (strcmp (ref->recovery, "watchdog") == 0 ||
	    strcmp (ref->recovery, "quit") == 0) {
		watchdog_ok = 0;
	}
	else if (strcmp (ref->recovery, "reboot") == 0) {
		reboot(RB_AUTOBOOT);
	}
	else if (strcmp (ref->recovery, "shutdown") == 0) {
		reboot(RB_POWER_OFF);
	}
	cs_fsm_state_set(fsm, WD_S_FAILED, data);
}
Beispiel #2
0
/*
 * return 0   - fully configured
 * return -1  - partially configured
 */
static int32_t wd_resource_create (hdb_handle_t resource_obj)
{
	int res;
	size_t len;
	char *state;
	objdb_value_types_t type;
	char period_str[32];
	char str_copy[256];
	char *str;
	uint64_t tmp_value;
	struct resource *ref = malloc (sizeof (struct resource));

	ref->handle = resource_obj;
	ref->check_timeout = WD_DEFAULT_TIMEOUT_MS;
	ref->check_timer = NULL;
	api->object_name_get (resource_obj,
		ref->name,
		&len);
	ref->name[len] = '\0';
	ref->fsm.name = ref->name;
	ref->fsm.table = wd_fsm_table;
	ref->fsm.entries = sizeof(wd_fsm_table) / sizeof(struct cs_fsm_entry);
	ref->fsm.curr_entry = 0;
	ref->fsm.curr_state = WD_S_STOPPED;
	ref->fsm.state_to_str = wd_res_state_to_str;
	ref->fsm.event_to_str = wd_res_event_to_str;
	api->object_priv_set (resource_obj, NULL);

	res = api->object_key_get_typed (resource_obj,
			"poll_period",
			(void**)&str, &len,
			&type);
	if (res != 0) {
		len = snprintf (period_str, 32, "%"PRIu64"", ref->check_timeout);
		api->object_key_create_typed (resource_obj,
			"poll_period", &period_str,
			len,
			OBJDB_VALUETYPE_STRING);
	}
	else {
		memcpy(str_copy, str, len);
		str_copy[len] = '\0';
		if (str_to_uint64_t(str_copy, &tmp_value, WD_MIN_TIMEOUT_MS, WD_MAX_TIMEOUT_MS) == CS_OK) {
			ref->check_timeout = tmp_value;
		} else {
			log_printf (LOGSYS_LEVEL_WARNING,
				"Could NOT use poll_period:%s ms for resource %s",
				str, ref->name);
		}
	}

	api->object_track_start (resource_obj, OBJECT_TRACK_DEPTH_RECURSIVE,
			wd_key_changed, NULL, wd_object_destroyed,
			NULL, ref);

	res = api->object_key_get_typed (resource_obj,
		"recovery", (void*)&ref->recovery, &len, &type);
	if (res != 0) {
		/* key does not exist.
		 */
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a recovery key.", ref->name);
		return -1;
	}
	res = api->object_key_get_typed (resource_obj,
		"state", (void*)&state, &len, &type);
	if (res != 0) {
		/* key does not exist.
		*/
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a state key.", ref->name);
		return -1;
	}

	res = api->object_key_get_typed (resource_obj,
		"last_updated", (void*)&ref->last_updated, &len, &type);
	if (res != 0) {
		/* key does not exist.
		 */
		ref->last_updated = 0;
	}

	/*
	 * delay the first check to give the monitor time to start working.
	 */
	tmp_value = CS_MAX(ref->check_timeout * 2, WD_DEFAULT_TIMEOUT_MS);
	api->timer_add_duration(tmp_value * MILLI_2_NANO_SECONDS,
		ref,
		wd_resource_check_fn, &ref->check_timer);

	cs_fsm_state_set(&ref->fsm, WD_S_RUNNING, ref);
	return 0;
}
Beispiel #3
0
/*
 * return 0   - fully configured
 * return -1  - partially configured
 */
static int32_t wd_resource_create (char *res_path, char *res_name)
{
	char *state;
	uint64_t tmp_value;
	struct resource *ref = calloc (1, sizeof (struct resource));
	char key_name[ICMAP_KEYNAME_MAXLEN];

	strcpy(ref->res_path, res_path);
	ref->check_timeout = WD_DEFAULT_TIMEOUT_MS;
	ref->check_timer = 0;

	strcpy(ref->name, res_name);
	ref->fsm.name = ref->name;
	ref->fsm.table = wd_fsm_table;
	ref->fsm.entries = sizeof(wd_fsm_table) / sizeof(struct cs_fsm_entry);
	ref->fsm.curr_entry = 0;
	ref->fsm.curr_state = WD_S_STOPPED;
	ref->fsm.state_to_str = wd_res_state_to_str;
	ref->fsm.event_to_str = wd_res_event_to_str;

	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "poll_period");
	if (icmap_get_uint64(key_name, &tmp_value) != CS_OK) {
		icmap_set_uint64(key_name, ref->check_timeout);
	} else {
		if (tmp_value >= WD_MIN_TIMEOUT_MS && tmp_value <= WD_MAX_TIMEOUT_MS) {
			ref->check_timeout = tmp_value;
		} else {
			log_printf (LOGSYS_LEVEL_WARNING,
				"Could NOT use poll_period:%"PRIu64" ms for resource %s",
				tmp_value, ref->name);
		}
	}

	icmap_track_add(res_path,
			ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY | ICMAP_TRACK_DELETE | ICMAP_TRACK_PREFIX,
			wd_key_changed,
			ref, &ref->icmap_track);

	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "recovery");
	if (icmap_get_string(key_name, &ref->recovery) != CS_OK) {
		/* key does not exist.
		 */
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a recovery key.", ref->name);
		return -1;
	}
	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "state");
	if (icmap_get_string(key_name, &state) != CS_OK) {
		/* key does not exist.
		*/
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a state key.", ref->name);
		return -1;
	}

	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "last_updated");
	if (icmap_get_uint64(key_name, &tmp_value) != CS_OK) {
		/* key does not exist.
		 */
		ref->last_updated = 0;
	} else {
		ref->last_updated = tmp_value;
	}

	/*
	 * delay the first check to give the monitor time to start working.
	 */
	tmp_value = CS_MAX(ref->check_timeout * 2, WD_DEFAULT_TIMEOUT_MS);
	api->timer_add_duration(tmp_value * MILLI_2_NANO_SECONDS,
		ref,
		wd_resource_check_fn, &ref->check_timer);

	cs_fsm_state_set(&ref->fsm, WD_S_RUNNING, ref);
	return 0;
}
Beispiel #4
0
static void wd_config_changed (struct cs_fsm* fsm, int32_t event, void * data)
{
	int res;
	size_t len;
	char *state;
	objdb_value_types_t type;
	char *str;
	uint64_t tmp_value;
	uint64_t next_timeout;
	struct resource *ref = (struct resource*)data;
	char str_copy[256];

	next_timeout = ref->check_timeout;

	res = api->object_key_get_typed (ref->handle,
			"poll_period",
			(void**)&str, &len,
			&type);
	if (res == 0) {
		memcpy(str_copy, str, len);
		str_copy[len] = '\0';
		if (str_to_uint64_t(str_copy, &tmp_value, WD_MIN_TIMEOUT_MS, WD_MAX_TIMEOUT_MS) == CS_OK) {
			log_printf (LOGSYS_LEVEL_DEBUG,
				"poll_period changing from:%"PRIu64" to %"PRIu64".",
				ref->check_timeout, tmp_value);
			/*
			 * To easy in the transition between poll_period's we are going
			 * to make the first timeout the bigger of the new and old value.
			 * This is to give the monitoring system time to adjust.
			 */
			next_timeout = CS_MAX(tmp_value, ref->check_timeout);
			ref->check_timeout = tmp_value;
		} else {
			log_printf (LOGSYS_LEVEL_WARNING,
				"Could NOT use poll_period:%s ms for resource %s",
				str, ref->name);
		}
	}

	res = api->object_key_get_typed (ref->handle,
		"recovery", (void*)&ref->recovery, &len, &type);
	if (res != 0) {
		/* key does not exist.
		 */
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a recovery key.", ref->name);
		cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref);
		return;
	}
	res = api->object_key_get_typed (ref->handle,
		"state", (void*)&state, &len, &type);
	if (res != 0) {
		/* key does not exist.
		*/
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a state key.", ref->name);
		cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref);
		return;
	}
	if (ref->check_timer) {
		api->timer_delete(ref->check_timer);
		ref->check_timer = NULL;
	}

	if (strcmp(wd_stopped_str, state) == 0) {
		cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref);
	} else {
		api->timer_add_duration(next_timeout * MILLI_2_NANO_SECONDS,
			ref, wd_resource_check_fn, &ref->check_timer);
		cs_fsm_state_set(&ref->fsm, WD_S_RUNNING, ref);
	}
}
Beispiel #5
0
static void wd_config_changed (struct cs_fsm* fsm, int32_t event, void * data)
{
	char *state;
	uint64_t tmp_value;
	uint64_t next_timeout;
	struct resource *ref = (struct resource*)data;
	char key_name[ICMAP_KEYNAME_MAXLEN];

	next_timeout = ref->check_timeout;

	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "poll_period");
	if (icmap_get_uint64(ref->res_path, &tmp_value) == CS_OK) {
		if (tmp_value >= WD_MIN_TIMEOUT_MS && tmp_value <= WD_MAX_TIMEOUT_MS) {
			log_printf (LOGSYS_LEVEL_DEBUG,
				"poll_period changing from:%"PRIu64" to %"PRIu64".",
				ref->check_timeout, tmp_value);
			/*
			 * To easy in the transition between poll_period's we are going
			 * to make the first timeout the bigger of the new and old value.
			 * This is to give the monitoring system time to adjust.
			 */
			next_timeout = CS_MAX(tmp_value, ref->check_timeout);
			ref->check_timeout = tmp_value;
		} else {
			log_printf (LOGSYS_LEVEL_WARNING,
				"Could NOT use poll_period:%"PRIu64" ms for resource %s",
				tmp_value, ref->name);
		}
	}

	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "recovery");
	if (icmap_get_string(key_name, &ref->recovery) != CS_OK) {
		/* key does not exist.
		 */
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a recovery key.", ref->name);
		cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref);
		return;
	}
	snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "state");
	if (icmap_get_string(key_name, &state) != CS_OK) {
		/* key does not exist.
		*/
		log_printf (LOGSYS_LEVEL_WARNING,
			"resource %s missing a state key.", ref->name);
		cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref);
		return;
	}
	if (ref->check_timer) {
		api->timer_delete(ref->check_timer);
		ref->check_timer = 0;
	}

	if (strcmp(wd_stopped_str, state) == 0) {
		cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref);
	} else {
		api->timer_add_duration(next_timeout * MILLI_2_NANO_SECONDS,
			ref, wd_resource_check_fn, &ref->check_timer);
		cs_fsm_state_set(&ref->fsm, WD_S_RUNNING, ref);
	}
	free(state);
}