示例#1
0
static void resource_execute_cb(struct pe_operation *op)
{
	struct resource *resource;
	struct assembly *assembly;

	qb_enter();

	assembly = qb_map_get(assembly_map, op->hostname);
	resource = qb_map_get(assembly->resource_map, op->rname);

	if (assembly->recover.state != RECOVER_STATE_RUNNING) {
		qb_log(LOG_DEBUG, "can't execute resource in offline state");
		resource_action_completed(op, OCF_UNKNOWN_ERROR);
		return;
	}
	qb_log(LOG_TRACE, "%s_%s_%d [%s] on %s target_rc:%d",
	       op->rname, op->method, op->interval, op->rclass, op->hostname,
	       op->target_outcome);

	qb_util_stopwatch_start(op->time_execed);

	op->resource = resource;
	if (strcmp(op->method, "monitor") == 0) {
		if (strstr(op->rname, op->hostname) != NULL) {
			assert(op->resource);
			if (op->interval > 0) {
				recurring_monitor_start(op);
			} else {
				resource_monitor_execute(op);
			}
		} else {
			qb_util_stopwatch_stop(op->time_execed);
			pe_resource_completed(op, OCF_NOT_RUNNING);
			pe_resource_unref(op);
		}
	} else if (strcmp (op->method, "start") == 0) {
		transport_resource_action(assembly, resource, op);
	} else if (strcmp(op->method, "stop") == 0) {
		if (resource->monitor_op) {
			recurring_monitor_stop(resource->monitor_op);
		}
		transport_resource_action(assembly, resource, op);
	} else if (strcmp(op->method, "delete") == 0) {
		op_history_delete(op);
	} else {
		assert(0);
	}

	qb_leave();
}
示例#2
0
void
resource_action_completed(struct pe_operation *op,
			  enum ocf_exitcode pe_exitcode)
{
	uint64_t el;
	struct assembly *a = qb_map_get(assembly_map, op->hostname);;
	struct resource *r = qb_map_get(a->resource_map, op->rname);

	qb_enter();

	op->times_executed++;
	qb_util_stopwatch_stop(op->time_execed);
	el = qb_util_stopwatch_us_elapsed_get(op->time_execed);

	qb_log(LOG_INFO, "%s_%s_%d [%s] on %s rc:[%d/%d] time:[%"PRIu64"/%ums]",
	       op->rname, op->method, op->interval, op->rclass, op->hostname,
	       pe_exitcode, op->target_outcome,
	       el / QB_TIME_US_IN_MSEC, op->timeout);

	if (strstr(op->rname, op->hostname) != NULL) {
		op_history_save(r, op, pe_exitcode);
	}

	if (op->times_executed <= 1) {
		pe_resource_completed(op, pe_exitcode);
	}

	resource_state_set(r, op, pe_exitcode);

	if (pe_exitcode != op->target_outcome) {
		schedule_processing();
	}
	if (op->interval > 0) {
		if (pe_exitcode != op->target_outcome) {
			/* unreference as not used by the timer anymore.
			 */
			pe_resource_unref(op);
		} else {
			qb_loop_timer_add(NULL, QB_LOOP_LOW,
					  op->interval * QB_TIME_NS_IN_MSEC, op,
					  resource_monitor_execute,
					  &r->monitor_timer);
		}
	} else {
		pe_resource_unref(op);
	}

	qb_leave();
}
示例#3
0
static void _cs_cmap_link_added_removed (
	cmap_handle_t cmap_handle_c,
	cmap_track_handle_t track_handle,
	int32_t event,
	const char *key_name,
	struct cmap_notify_value new_value,
	struct cmap_notify_value old_value,
	void *user_data)
{
	struct track_item *track_item;

	/* Add/remove a tracker for a new/removed knet link */
	if (strstr(key_name, ".connected")) {
		if (event == CMAP_TRACK_ADD) {

			track_item = malloc(sizeof(struct track_item));
			if (!track_item) {
				return;
			}
			cmap_track_add(stats_handle, key_name, CMAP_TRACK_MODIFY, _cs_cmap_link_faulty_key_changed, NULL, &track_handle);

			strcpy(track_item->key_name, key_name);
			track_item->track_handle = track_handle;
			qb_map_put(tracker_map, track_item->key_name, track_item);
		} else {
			track_item = qb_map_get(tracker_map, key_name);
			if (track_item) {
				cmap_track_delete(stats_handle, track_item->track_handle);
				qb_map_rm(tracker_map, track_item->key_name);
				free(track_item);
			}
		}
	}
}
示例#4
0
cs_error_t icmap_adjust_int(
	const char *key_name,
	int32_t step)
{
	struct icmap_item *item;
	uint8_t u8;
	uint16_t u16;
	uint32_t u32;
	uint64_t u64;
	cs_error_t err = CS_OK;

	if (key_name == NULL) {
		return (CS_ERR_INVALID_PARAM);
	}

	item = qb_map_get(icmap_map, key_name);
	if (item == NULL) {
		return (CS_ERR_NOT_EXIST);
	}

	switch (item->type) {
	case ICMAP_VALUETYPE_INT8:
	case ICMAP_VALUETYPE_UINT8:
		memcpy(&u8, item->value, sizeof(u8));
		u8 += step;
		err = icmap_set(key_name, &u8, sizeof(u8), item->type);
		break;
	case ICMAP_VALUETYPE_INT16:
	case ICMAP_VALUETYPE_UINT16:
		memcpy(&u16, item->value, sizeof(u16));
		u16 += step;
		err = icmap_set(key_name, &u16, sizeof(u16), item->type);
		break;
	case ICMAP_VALUETYPE_INT32:
	case ICMAP_VALUETYPE_UINT32:
		memcpy(&u32, item->value, sizeof(u32));
		u32 += step;
		err = icmap_set(key_name, &u32, sizeof(u32), item->type);
		break;
	case ICMAP_VALUETYPE_INT64:
	case ICMAP_VALUETYPE_UINT64:
		memcpy(&u64, item->value, sizeof(u64));
		u64 += step;
		err = icmap_set(key_name, &u64, sizeof(u64), item->type);
		break;
	case ICMAP_VALUETYPE_FLOAT:
	case ICMAP_VALUETYPE_DOUBLE:
	case ICMAP_VALUETYPE_STRING:
	case ICMAP_VALUETYPE_BINARY:
		err = CS_ERR_INVALID_PARAM;
		break;
	}

	return (err);
}
示例#5
0
static void
resource_monitor_execute(void *data)
{
	struct pe_operation *op = (struct pe_operation *)data;
	struct assembly *assembly;
	struct resource *resource;

	qb_enter();

	assembly = qb_map_get(assembly_map, op->hostname);
	resource = qb_map_get(assembly->resource_map, op->rname);

	if (assembly->recover.state != RECOVER_STATE_RUNNING) {
		qb_log(LOG_DEBUG, "can't execute resource in offline state");
		resource_action_completed(op, OCF_UNKNOWN_ERROR);
		return;
	}
	qb_util_stopwatch_start(op->time_execed);
	transport_resource_action(assembly, resource, op);

	qb_leave();
}
示例#6
0
cs_error_t icmap_fast_adjust_int(
	const char *key_name,
	int32_t step)
{
	struct icmap_item *item;
	cs_error_t err = CS_OK;

	if (key_name == NULL) {
		return (CS_ERR_INVALID_PARAM);
	}

	item = qb_map_get(icmap_map, key_name);
	if (item == NULL) {
		return (CS_ERR_NOT_EXIST);
	}

	switch (item->type) {
	case ICMAP_VALUETYPE_INT8:
	case ICMAP_VALUETYPE_UINT8:
		*(uint8_t *)item->value += step;
		break;
	case ICMAP_VALUETYPE_INT16:
	case ICMAP_VALUETYPE_UINT16:
		*(uint16_t *)item->value += step;
		break;
	case ICMAP_VALUETYPE_INT32:
	case ICMAP_VALUETYPE_UINT32:
		*(uint32_t *)item->value += step;
		break;
	case ICMAP_VALUETYPE_INT64:
	case ICMAP_VALUETYPE_UINT64:
		*(uint64_t *)item->value += step;
		break;
	case ICMAP_VALUETYPE_FLOAT:
	case ICMAP_VALUETYPE_DOUBLE:
	case ICMAP_VALUETYPE_STRING:
	case ICMAP_VALUETYPE_BINARY:
		err = CS_ERR_INVALID_PARAM;
		break;
	}

	if (err == CS_OK) {
		qb_map_put(icmap_map, item->key_name, item);
	}

	return (err);
}
示例#7
0
cs_error_t icmap_delete(const char *key_name)
{
	struct icmap_item *item;

	if (key_name == NULL) {
		return (CS_ERR_INVALID_PARAM);
	}

	item = qb_map_get(icmap_map, key_name);
	if (item == NULL) {
		return (CS_ERR_NOT_EXIST);
	}

	if (qb_map_rm(icmap_map, item->key_name) != QB_TRUE) {
		return (CS_ERR_NOT_EXIST);
	}

	return (CS_OK);
}
示例#8
0
static void op_history_save(struct resource *resource, struct pe_operation *op,
	enum ocf_exitcode ec)
{
	struct operation_history *oh;
	/*
	 * +3 = _ _ and null terminator
	 */
	char buffer[RESOURCE_NAME_MAX + METHOD_NAME_MAX + OP_NAME_MAX + 3];

	qb_enter();

	snprintf(buffer,
		RESOURCE_NAME_MAX + METHOD_NAME_MAX + OP_NAME_MAX + 3,
		"%s_%s_%d", op->rname, op->method, op->interval);

	oh = qb_map_get(op_history_map, buffer);
	if (oh == NULL) {
		oh = (struct operation_history *)calloc(1, sizeof(struct operation_history));
		oh->resource = resource;
		oh->rsc_id = strdup(buffer);
		oh->operation = strdup(op->method);
		oh->target_outcome = op->target_outcome;
		oh->interval = op->interval;
		oh->rc = OCF_PENDING;
		oh->op_digest = strdup(op->op_digest);
		qb_map_put(op_history_map, oh->rsc_id, oh);
	} else
	if (strcmp(oh->op_digest, op->op_digest) != 0) {
		free(oh->op_digest);
		oh->op_digest = op->op_digest;
	}
        if (oh->rc != ec) {
                oh->last_rc_change = time(NULL);
                oh->rc = ec;
        }

        oh->last_run = time(NULL);
        oh->call_id = call_order++;
        oh->graph_id = op->graph_id;
        oh->action_id = op->action_id;

	qb_leave();
}
示例#9
0
cs_error_t icmap_get(
	const char *key_name,
	void *value,
	size_t *value_len,
	icmap_value_types_t *type)
{
	struct icmap_item *item;

	if (key_name == NULL) {
		return (CS_ERR_INVALID_PARAM);
	}

	item = qb_map_get(icmap_map, key_name);
	if (item == NULL) {
		return (CS_ERR_NOT_EXIST);
	}

	if (type != NULL) {
		*type = item->type;
	}

	if (value == NULL) {
		if (value_len != NULL) {
			*value_len = item->value_len;
		}
	} else {
		if (value_len == NULL || *value_len < item->value_len) {
			return (CS_ERR_INVALID_PARAM);
		}

		*value_len = item->value_len;

		memcpy(value, item->value, item->value_len);
	}

	return (CS_OK);
}
示例#10
0
cs_error_t icmap_set(
	const char *key_name,
	const void *value,
	size_t value_len,
	icmap_value_types_t type)
{
	struct icmap_item *item;
	struct icmap_item *new_item;
	size_t new_value_len;
	size_t new_item_size;

	if (value == NULL || key_name == NULL) {
		return (CS_ERR_INVALID_PARAM);
	}

	if (icmap_check_value_len(value, value_len, type) != 0) {
		return (CS_ERR_INVALID_PARAM);
	}

	item = qb_map_get(icmap_map, key_name);
	if (item != NULL) {
		/*
		 * Check that key is really changed
		 */
		if (icmap_item_eq(item, value, value_len, type)) {
			return (CS_OK);
		}
	} else {
		if (icmap_check_key_name(key_name) != 0) {
			return (CS_ERR_NAME_TOO_LONG);
		}
	}

	if (type == ICMAP_VALUETYPE_BINARY || type == ICMAP_VALUETYPE_STRING) {
		if (type == ICMAP_VALUETYPE_STRING) {
			new_value_len = strlen((const char *)value);
			if (new_value_len > value_len) {
				new_value_len = value_len;
			}
			new_value_len++;
		} else {
			new_value_len = value_len;
		}
	} else {
		new_value_len = icmap_get_valuetype_len(type);
	}

	new_item_size = sizeof(struct icmap_item) + new_value_len;
	new_item = malloc(new_item_size);
	if (new_item == NULL) {
		return (CS_ERR_NO_MEMORY);
	}
	memset(new_item, 0, new_item_size);

	if (item == NULL) {
		new_item->key_name = strdup(key_name);
		if (new_item->key_name == NULL) {
			free(new_item);
			return (CS_ERR_NO_MEMORY);
		}
	} else {
		new_item->key_name = item->key_name;
		item->key_name = NULL;
	}

	new_item->type = type;
	new_item->value_len = new_value_len;

	memcpy(new_item->value, value, new_value_len);

	if (new_item->type == ICMAP_VALUETYPE_STRING) {
		((char *)new_item->value)[new_value_len - 1] = 0;
	}

	qb_map_put(icmap_map, new_item->key_name, new_item);

	return (CS_OK);
}