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(); }
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(); }
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); } } } }
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); }
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(); }
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); }
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); }
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(); }
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); }
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); }