diff --git a/daemons/controld/controld_alerts.c b/daemons/controld/controld_alerts.c index a3dd5b6d5f2..7833d68e930 100644 --- a/daemons/controld/controld_alerts.c +++ b/daemons/controld/controld_alerts.c @@ -71,7 +71,7 @@ crmd_alert_fencing_op(stonith_event_t * e) } void -crmd_alert_resource_op(const char *node, lrmd_event_data_t * op) +crmd_alert_resource_op(const char *node, const lrmd_event_data_t *op) { lrm_state_t *lrm_state; diff --git a/daemons/controld/controld_alerts.h b/daemons/controld/controld_alerts.h index 441c8fefdff..9e822771b13 100644 --- a/daemons/controld/controld_alerts.h +++ b/daemons/controld/controld_alerts.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2024 the Pacemaker project contributors + * Copyright 2015-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -19,6 +19,6 @@ void crmd_unpack_alerts(xmlNode *alerts); void crmd_alert_node_event(pcmk__node_status_t *node); void crmd_alert_fencing_op(stonith_event_t *e); -void crmd_alert_resource_op(const char *node, lrmd_event_data_t *op); +void crmd_alert_resource_op(const char *node, const lrmd_event_data_t *op); #endif diff --git a/daemons/controld/controld_cib.c b/daemons/controld/controld_cib.c index 017bdab4516..e8020759716 100644 --- a/daemons/controld/controld_cib.c +++ b/daemons/controld/controld_cib.c @@ -518,7 +518,7 @@ build_parameter_list(const lrmd_event_data_t *op, } static void -append_restart_list(lrmd_event_data_t *op, struct ra_metadata_s *metadata, +append_restart_list(const lrmd_event_data_t *op, struct ra_metadata_s *metadata, xmlNode *update, const char *version) { GString *list = NULL; @@ -576,7 +576,7 @@ append_restart_list(lrmd_event_data_t *op, struct ra_metadata_s *metadata, } static void -append_secure_list(lrmd_event_data_t *op, struct ra_metadata_s *metadata, +append_secure_list(const lrmd_event_data_t *op, struct ra_metadata_s *metadata, xmlNode *update, const char *version) { GString *list = NULL; @@ -753,7 +753,7 @@ cib_rsc_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *use * until it is active there again after the node comes back up. */ static bool -should_preserve_lock(lrmd_event_data_t *op) +should_preserve_lock(const lrmd_event_data_t *op) { if (!pcmk__is_set(controld_globals.flags, controld_shutdown_lock_enabled)) { return false; diff --git a/daemons/controld/controld_execd.c b/daemons/controld/controld_execd.c index 24d3c415d6d..46a5a67783c 100644 --- a/daemons/controld/controld_execd.c +++ b/daemons/controld/controld_execd.c @@ -152,7 +152,8 @@ history_free(gpointer data) } static void -update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op) +update_history_cache(lrm_state_t *lrm_state, lrmd_rsc_info_t *rsc, + const lrmd_event_data_t *op) { int target_rc = 0; rsc_history_t *entry = NULL; @@ -269,7 +270,7 @@ send_task_ok_ack(const lrm_state_t *lrm_state, const ha_msg_input_t *input, } static inline const char * -op_node_name(lrmd_event_data_t *op) +op_node_name(const lrmd_event_data_t *op) { return pcmk__s(op->remote_nodename, controld_globals.cluster->priv->node_name); @@ -1725,11 +1726,13 @@ controld_ack_event_directly(const char *to_host, const char *to_sys, pcmk__node_status_t *peer = NULL; CRM_CHECK(op != NULL, return); + if (op->rsc_id == NULL) { - // op->rsc_id is a (const char *) but lrmd_free_event() frees it - pcmk__assert(rsc_id != NULL); op->rsc_id = pcmk__str_copy(rsc_id); } + + pcmk__assert(op->rsc_id != NULL); + if (to_sys == NULL) { to_sys = CRM_SYSTEM_TENGINE; } diff --git a/daemons/controld/controld_execd_state.c b/daemons/controld/controld_execd_state.c index 68ad291646b..a9cc9ae2283 100644 --- a/daemons/controld/controld_execd_state.c +++ b/daemons/controld/controld_execd_state.c @@ -55,31 +55,28 @@ free_recurring_op(gpointer value) static gboolean fail_pending_op(gpointer key, gpointer value, gpointer user_data) { - lrmd_event_data_t event = { 0, }; lrm_state_t *lrm_state = user_data; active_op_t *op = value; + lrmd_event_data_t *event = lrmd_new_event(op->rsc_id, op->op_type, + op->interval_ms); pcmk__trace("Pre-emptively failing " PCMK__OP_FMT " on %s (call=%s, %s)", op->rsc_id, op->op_type, op->interval_ms, lrm_state->node_name, (const char *) key, op->user_data); - event.type = lrmd_event_exec_complete; - event.rsc_id = op->rsc_id; - event.op_type = op->op_type; - event.user_data = op->user_data; - event.timeout = 0; - event.interval_ms = op->interval_ms; - lrmd__set_result(&event, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_NOT_CONNECTED, + event->type = lrmd_event_exec_complete; + event->user_data = pcmk__str_copy(op->user_data); + lrmd__set_result(event, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_NOT_CONNECTED, "Action was pending when executor connection was dropped"); - event.t_run = op->start_time; - event.t_rcchange = op->start_time; + event->t_run = op->start_time; + event->t_rcchange = op->start_time; - event.call_id = op->call_id; - event.remote_nodename = lrm_state->node_name; - event.params = op->params; + event->call_id = op->call_id; + event->remote_nodename = pcmk__str_copy(lrm_state->node_name); + event->params = op->params; - process_lrm_event(lrm_state, &event, op, NULL); - lrmd__reset_result(&event); + process_lrm_event(lrm_state, event, op, NULL); + lrmd_free_event(event); return TRUE; } diff --git a/daemons/controld/controld_remote_ra.c b/daemons/controld/controld_remote_ra.c index 695bf55af4d..45fba1df747 100644 --- a/daemons/controld/controld_remote_ra.c +++ b/daemons/controld/controld_remote_ra.c @@ -399,26 +399,24 @@ check_remote_node_state(const remote_ra_cmd_t *cmd) static void report_remote_ra_result(remote_ra_cmd_t * cmd) { - lrmd_event_data_t op = { 0, }; + lrmd_event_data_t *event = lrmd_new_event(cmd->rsc_id, cmd->action, + cmd->interval_ms); check_remote_node_state(cmd); - op.type = lrmd_event_exec_complete; - op.rsc_id = cmd->rsc_id; - op.op_type = cmd->action; - op.user_data = cmd->userdata; - op.timeout = cmd->timeout; - op.interval_ms = cmd->interval_ms; - op.t_run = cmd->start_time; - op.t_rcchange = cmd->start_time; + event->type = lrmd_event_exec_complete; + event->user_data = pcmk__str_copy(cmd->userdata); + event->timeout = cmd->timeout; + event->t_run = cmd->start_time; + event->t_rcchange = cmd->start_time; - lrmd__set_result(&op, cmd->result.exit_status, cmd->result.execution_status, - cmd->result.exit_reason); + lrmd__set_result(event, cmd->result.exit_status, + cmd->result.execution_status, cmd->result.exit_reason); if (pcmk__is_set(cmd->status, cmd_reported_success) && !pcmk__result_ok(&(cmd->result))) { - op.t_rcchange = time(NULL); + event->t_rcchange = time(NULL); /* This edge case will likely never ever occur, but if it does the * result is that a failure will not be processed correctly. This is only * remotely possible because we are able to detect a connection resource's tcp @@ -428,27 +426,25 @@ report_remote_ra_result(remote_ra_cmd_t * cmd) * basically, we are not guaranteed that the first successful monitor op and * a subsequent failed monitor op will not occur in the same timestamp. We have to * make it look like the operations occurred at separate times though. */ - if (op.t_rcchange == op.t_run) { - op.t_rcchange++; + if (event->t_rcchange == event->t_run) { + event->t_rcchange++; } } if (cmd->params) { lrmd_key_value_t *tmp; - op.params = pcmk__strkey_table(free, free); + event->params = pcmk__strkey_table(free, free); for (tmp = cmd->params; tmp; tmp = tmp->next) { - pcmk__insert_dup(op.params, tmp->key, tmp->value); + pcmk__insert_dup(event->params, tmp->key, tmp->value); } } - op.call_id = cmd->call_id; - op.remote_nodename = cmd->owner; + event->call_id = cmd->call_id; + event->remote_nodename = pcmk__str_copy(cmd->owner); - lrm_op_callback(&op); - - g_clear_pointer(&op.params, g_hash_table_destroy); - lrmd__reset_result(&op); + lrm_op_callback(event); + lrmd_free_event(event); } /*! @@ -562,7 +558,7 @@ monitor_timeout_cb(gpointer data) static void synthesize_lrmd_success(lrm_state_t *lrm_state, const char *rsc_id, const char *op_type) { - lrmd_event_data_t op = { 0, }; + lrmd_event_data_t *event = NULL; if (lrm_state == NULL) { /* if lrm_state not given assume local */ @@ -570,14 +566,13 @@ synthesize_lrmd_success(lrm_state_t *lrm_state, const char *rsc_id, const char * } pcmk__assert(lrm_state != NULL); - op.type = lrmd_event_exec_complete; - op.rsc_id = rsc_id; - op.op_type = op_type; - op.t_run = time(NULL); - op.t_rcchange = op.t_run; - op.call_id = generate_callid(); - lrmd__set_result(&op, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL); - process_lrm_event(lrm_state, &op, NULL, NULL); + event = lrmd_new_event(rsc_id, op_type, 0); + event->type = lrmd_event_exec_complete; + event->t_run = time(NULL); + event->t_rcchange = event->t_run; + event->call_id = generate_callid(); + lrmd__set_result(event, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL); + process_lrm_event(lrm_state, event, NULL, NULL); } void diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c index 1095b722e5f..0cb5ee1599b 100644 --- a/daemons/execd/execd_commands.c +++ b/daemons/execd/execd_commands.c @@ -1015,8 +1015,8 @@ action_complete(svc_action_t * action) #endif finalize: - pcmk__set_result_output(&(cmd->result), services__grab_stdout(action), - services__grab_stderr(action)); + cmd->result.action_stdout = pcmk__str_copy(action->stdout_data); + cmd->result.action_stderr = pcmk__str_copy(action->stderr_data); cmd_finalize(cmd, rsc); } diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c index 8c5da82a325..74f339e3c2c 100644 --- a/daemons/fenced/fenced_commands.c +++ b/daemons/fenced/fenced_commands.c @@ -1953,40 +1953,6 @@ fenced_unregister_level(xmlNode *msg, pcmk__action_result_t *result) pcmk__set_result(result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); } -static char * -list_to_string(GList *list, const char *delim, gboolean terminate_with_delim) -{ - int max = g_list_length(list); - size_t delim_len = delim?strlen(delim):0; - size_t alloc_size = 1 + (max?((max-1+(terminate_with_delim?1:0))*delim_len):0); - char *rv; - - char *pos = NULL; - const char *lead_delim = ""; - - for (const GList *iter = list; iter != NULL; iter = iter->next) { - const char *value = (const char *) iter->data; - - alloc_size += strlen(value); - } - - rv = pcmk__assert_alloc(alloc_size, sizeof(char)); - pos = rv; - - for (const GList *iter = list; iter != NULL; iter = iter->next) { - const char *value = (const char *) iter->data; - - pos = &pos[sprintf(pos, "%s%s", lead_delim, value)]; - lead_delim = delim; - } - - if ((max != 0) && terminate_with_delim) { - sprintf(pos, "%s", delim); - } - - return rv; -} - /*! * \internal * \brief Execute a fence agent action directly (and asynchronously) @@ -2028,17 +1994,25 @@ execute_agent_action(xmlNode *msg, pcmk__action_result_t *result) if (fencing_watchdog_timeout_ms <= 0) { pcmk__set_result(result, CRM_EX_ERROR, PCMK_EXEC_NO_FENCE_DEVICE, "Watchdog fence device not configured"); - return; + } + + if (pcmk__str_eq(action, PCMK_ACTION_LIST, pcmk__str_none)) { + GString *buf = g_string_sized_new(64); + + for (const GList *iter = stonith_watchdog_targets; iter != NULL; + iter = iter->next) { + + g_string_append(buf, iter->data); + g_string_append_c(buf, '\n'); + } - } else if (pcmk__str_eq(action, PCMK_ACTION_LIST, pcmk__str_none)) { pcmk__set_result(result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); - pcmk__set_result_output(result, - list_to_string(stonith_watchdog_targets, - "\n", TRUE), - NULL); + result->action_stdout = pcmk__str_copy(buf->str); + g_string_free(buf, TRUE); return; + } - } else if (pcmk__str_eq(action, PCMK_ACTION_MONITOR, pcmk__str_none)) { + if (pcmk__str_eq(action, PCMK_ACTION_MONITOR, pcmk__str_none)) { pcmk__set_result(result, CRM_EX_OK, PCMK_EXEC_DONE, NULL); return; } @@ -2052,9 +2026,11 @@ execute_agent_action(xmlNode *msg, pcmk__action_result_t *result) pcmk__format_result(result, CRM_EX_ERROR, PCMK_EXEC_NO_FENCE_DEVICE, "'%s' not found", id); return; + } + + if (!pcmk__is_set(device->flags, fenced_df_api_registered) + && pcmk__str_eq(action, PCMK_ACTION_MONITOR, pcmk__str_none)) { - } else if (!pcmk__is_set(device->flags, fenced_df_api_registered) - && (strcmp(action, PCMK_ACTION_MONITOR) == 0)) { // Monitors may run only on "started" (API-registered) devices pcmk__info("Ignoring API '%s' action request because device %s not " "active", diff --git a/daemons/fenced/fenced_history.c b/daemons/fenced/fenced_history.c index 58861d35c9e..6021e364e62 100644 --- a/daemons/fenced/fenced_history.c +++ b/daemons/fenced/fenced_history.c @@ -284,10 +284,9 @@ stonith_xml_history_to_list(const xmlNode *history) } pcmk__set_result(&op->result, exit_status, execution_status, pcmk__xe_get(xml_op, PCMK_XA_EXIT_REASON)); - pcmk__set_result_output(&op->result, - pcmk__xe_get_copy(xml_op, PCMK__XA_ST_OUTPUT), - NULL); + op->result.action_stdout = pcmk__xe_get_copy(xml_op, + PCMK__XA_ST_OUTPUT); g_hash_table_replace(rv, id, op); CRM_LOG_ASSERT(g_hash_table_lookup(rv, id) != NULL); diff --git a/include/crm/common/actions.h b/include/crm/common/actions.h index 7c457656865..dfa779f231f 100644 --- a/include/crm/common/actions.h +++ b/include/crm/common/actions.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 the Pacemaker project contributors + * Copyright 2004-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -77,7 +77,7 @@ gboolean decode_transition_magic(const char *magic, char **uuid, // @COMPAT Either these shouldn't be in libcrmcommon or lrmd_event_data_t should int rsc_op_expected_rc(const lrmd_event_data_t *event); -gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc); +gboolean did_rsc_op_fail(const lrmd_event_data_t *event, int target_rc); bool crm_op_needs_metadata(const char *rsc_class, const char *op); diff --git a/include/crm/common/alerts_internal.h b/include/crm/common/alerts_internal.h index 1363ffe5d7e..2abe74ddcf9 100644 --- a/include/crm/common/alerts_internal.h +++ b/include/crm/common/alerts_internal.h @@ -80,7 +80,6 @@ enum pcmk__alert_keys_e { extern const char *pcmk__alert_keys[PCMK__ALERT_INTERNAL_KEY_MAX]; -pcmk__alert_t *pcmk__dup_alert(const pcmk__alert_t *entry); pcmk__alert_t *pcmk__alert_new(const char *id, const char *path); void pcmk__free_alert(pcmk__alert_t *entry); void pcmk__add_alert_key(GHashTable *table, enum pcmk__alert_keys_e name, diff --git a/include/crm/common/results_internal.h b/include/crm/common/results_internal.h index 0bff95c33cd..da3383ce4e2 100644 --- a/include/crm/common/results_internal.h +++ b/include/crm/common/results_internal.h @@ -78,9 +78,6 @@ void pcmk__format_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *format, ...) G_GNUC_PRINTF(4, 5); -void pcmk__set_result_output(pcmk__action_result_t *result, - char *out, char *err); - void pcmk__reset_result(pcmk__action_result_t *result); void pcmk__copy_result(const pcmk__action_result_t *src, diff --git a/include/crm/lrmd_events.h b/include/crm/lrmd_events.h index c30b0b4a9a4..ff718b09e25 100644 --- a/include/crm/lrmd_events.h +++ b/include/crm/lrmd_events.h @@ -45,11 +45,11 @@ typedef struct lrmd_event_data_s { enum lrmd_callback_event type; /*! The resource this event occurred on. */ - const char *rsc_id; + char *rsc_id; /*! The action performed, start, stop, monitor... */ - const char *op_type; + char *op_type; /*! The user data passed by caller of exec() API function */ - const char *user_data; + char *user_data; /*! The client api call id associated with this event */ int call_id; @@ -73,7 +73,7 @@ typedef struct lrmd_event_data_s { int op_status; /*! stdout from resource agent operation */ - const char *output; + char *output; /*! Timestamp of when op ran */ time_t t_run; @@ -97,15 +97,15 @@ typedef struct lrmd_event_data_s { /*! client node name associated with this connection * (used to match actions to the proper client when there are multiple) */ - const char *remote_nodename; + char *remote_nodename; /*! exit failure reason string from resource agent operation */ - const char *exit_reason; + char *exit_reason; } lrmd_event_data_t; lrmd_event_data_t *lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms); -lrmd_event_data_t *lrmd_copy_event(lrmd_event_data_t *event); +lrmd_event_data_t *lrmd_copy_event(const lrmd_event_data_t *event); void lrmd_free_event(lrmd_event_data_t *event); #ifdef __cplusplus diff --git a/include/crm/lrmd_internal.h b/include/crm/lrmd_internal.h index 9e0c5fcc6d1..53211131ca3 100644 --- a/include/crm/lrmd_internal.h +++ b/include/crm/lrmd_internal.h @@ -49,8 +49,6 @@ void lrmd__metadata_async(const lrmd_rsc_info_t *rsc, void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, const char *exit_reason); -void lrmd__reset_result(lrmd_event_data_t *event); - time_t lrmd__uptime(lrmd_t *lrmd); const char *lrmd__node_start_state(lrmd_t *lrmd); diff --git a/include/crm/services_internal.h b/include/crm/services_internal.h index c282813eb96..9483426a504 100644 --- a/include/crm/services_internal.h +++ b/include/crm/services_internal.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2025 the Pacemaker project contributors + * Copyright 2010-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -47,8 +47,6 @@ svc_action_t *services__create_resource_action(const char *name, enum svc_action_flags flags); const char *services__exit_reason(const svc_action_t *action); -char *services__grab_stdout(svc_action_t *action); -char *services__grab_stderr(svc_action_t *action); void services__set_result(svc_action_t *action, int agent_status, enum pcmk_exec_status exec_status, diff --git a/lib/cib/cib_client.c b/lib/cib/cib_client.c index 83f55b6f15c..d0163312b3c 100644 --- a/lib/cib/cib_client.c +++ b/lib/cib/cib_client.c @@ -606,11 +606,7 @@ cib_new_variant(void) { cib_t *new_cib = NULL; - new_cib = calloc(1, sizeof(cib_t)); - - if (new_cib == NULL) { - return NULL; - } + new_cib = pcmk__assert_alloc(1, sizeof(cib_t)); remove_cib_op_callback(0, TRUE); /* remove all */ @@ -623,12 +619,7 @@ cib_new_variant(void) new_cib->notify_list = NULL; /* the rest will get filled in by the variant constructor */ - new_cib->cmds = calloc(1, sizeof(cib_api_operations_t)); - - if (new_cib->cmds == NULL) { - free(new_cib); - return NULL; - } + new_cib->cmds = pcmk__assert_alloc(1, sizeof(cib_api_operations_t)); new_cib->cmds->add_notify_callback = cib_client_add_notify_callback; new_cib->cmds->del_notify_callback = cib_client_del_notify_callback; diff --git a/lib/cib/cib_file.c b/lib/cib/cib_file.c index f409b3e61d4..4524d062021 100644 --- a/lib/cib/cib_file.c +++ b/lib/cib/cib_file.c @@ -758,23 +758,9 @@ cib_file_new(const char *cib_location) } cib = cib_new_variant(); - if (cib == NULL) { - return NULL; - } - - filename = strdup(cib_location); - if (filename == NULL) { - free(cib); - return NULL; - } - - private = calloc(1, sizeof(file_opaque_t)); - if (private == NULL) { - free(cib); - free(filename); - return NULL; - } + filename = pcmk__str_copy(cib_location); + private = pcmk__assert_alloc(1, sizeof(file_opaque_t)); private->id = pcmk__generate_uuid(); private->filename = filename; diff --git a/lib/cib/cib_native.c b/lib/cib/cib_native.c index 57c8c87545e..e8bf64d8b4d 100644 --- a/lib/cib/cib_native.c +++ b/lib/cib/cib_native.c @@ -489,19 +489,9 @@ cib_native_client_id(const cib_t *cib, const char **async_id, cib_t * cib_native_new(void) { - cib_native_opaque_t *native = NULL; cib_t *cib = cib_new_variant(); - - if (cib == NULL) { - return NULL; - } - - native = calloc(1, sizeof(cib_native_opaque_t)); - - if (native == NULL) { - free(cib); - return NULL; - } + cib_native_opaque_t *native = + pcmk__assert_alloc(1, sizeof(cib_native_opaque_t)); cib->variant = cib_native; cib->variant_opaque = native; diff --git a/lib/cib/cib_remote.c b/lib/cib/cib_remote.c index c2d0fc63e74..dc0c1e2665e 100644 --- a/lib/cib/cib_remote.c +++ b/lib/cib/cib_remote.c @@ -717,19 +717,9 @@ cib_t * cib_remote_new(const char *server, const char *user, const char *passwd, int port, gboolean encrypted) { - cib_remote_opaque_t *private = NULL; cib_t *cib = cib_new_variant(); - - if (cib == NULL) { - return NULL; - } - - private = calloc(1, sizeof(cib_remote_opaque_t)); - - if (private == NULL) { - free(cib); - return NULL; - } + cib_remote_opaque_t *private = + pcmk__assert_alloc(1, sizeof(cib_remote_opaque_t)); cib->variant = cib_remote; cib->variant_opaque = private; diff --git a/lib/common/actions.c b/lib/common/actions.c index b4a4ee04c19..04bdd741713 100644 --- a/lib/common/actions.c +++ b/lib/common/actions.c @@ -508,9 +508,9 @@ rsc_op_expected_rc(const lrmd_event_data_t *op) } gboolean -did_rsc_op_fail(lrmd_event_data_t * op, int target_rc) +did_rsc_op_fail(const lrmd_event_data_t *event, int target_rc) { - switch (op->op_status) { + switch (event->op_status) { case PCMK_EXEC_CANCELLED: case PCMK_EXEC_PENDING: return FALSE; @@ -525,7 +525,7 @@ did_rsc_op_fail(lrmd_event_data_t * op, int target_rc) return TRUE; default: - if (target_rc != op->rc) { + if (target_rc != event->rc) { return TRUE; } } diff --git a/lib/common/alerts.c b/lib/common/alerts.c index 6906c74059d..6be53f3d7d9 100644 --- a/lib/common/alerts.c +++ b/lib/common/alerts.c @@ -77,30 +77,6 @@ pcmk__free_alert(pcmk__alert_t *entry) } } -/*! - * \internal - * \brief Duplicate an alert entry - * - * \param[in] entry Alert entry to duplicate - * - * \return Duplicate of alert entry - */ -pcmk__alert_t * -pcmk__dup_alert(const pcmk__alert_t *entry) -{ - pcmk__alert_t *new_entry = pcmk__alert_new(entry->id, entry->path); - - new_entry->timeout = entry->timeout; - new_entry->flags = entry->flags; - new_entry->envvars = pcmk__str_table_dup(entry->envvars); - new_entry->tstamp_format = pcmk__str_copy(entry->tstamp_format); - new_entry->recipient = pcmk__str_copy(entry->recipient); - if (entry->select_attribute_name) { - new_entry->select_attribute_name = g_strdupv(entry->select_attribute_name); - } - return new_entry; -} - void pcmk__add_alert_key(GHashTable *table, enum pcmk__alert_keys_e name, const char *value) @@ -346,6 +322,34 @@ unpack_alert(xmlNode *alert, pcmk__alert_t *entry, guint *max_timeout) return rc; } +/*! + * \internal + * \brief Copy an alert entry + * + * This creates a deep copy of \p entry, except that the new object's + * \c recipient field is copied from \p recipient instead of from \p entry. + * \p recipient is a \c PCMK_XE_RECIPIENT element, and its \c PCMK_XA_VALUE + * attribute is copied as the new object's \c recipient field. + * + * \param[in] entry Alert entry to copy + * \param[in] recipient Recipient XML + * + * \return Copy of alert entry + */ +static pcmk__alert_t * +copy_alert(const pcmk__alert_t *entry, const xmlNode *recipient) +{ + pcmk__alert_t *new_entry = pcmk__alert_new(entry->id, entry->path); + + new_entry->tstamp_format = pcmk__str_copy(entry->tstamp_format); + new_entry->recipient = pcmk__xe_get_copy(recipient, PCMK_XA_VALUE); + new_entry->select_attribute_name = g_strdupv(entry->select_attribute_name); + new_entry->envvars = pcmk__str_table_dup(entry->envvars); + new_entry->timeout = entry->timeout; + new_entry->flags = entry->flags; + return new_entry; +} + /*! * \internal * \brief Unpack a CIB alerts section into a list of alert entries @@ -405,12 +409,10 @@ pcmk__unpack_alerts(const xmlNode *alerts) recipient != NULL; recipient = pcmk__xe_next(recipient, PCMK_XE_RECIPIENT)) { - pcmk__alert_t *recipient_entry = pcmk__dup_alert(entry); + pcmk__alert_t *recipient_entry = copy_alert(entry, recipient); guint n_envvars = 0; recipients++; - recipient_entry->recipient = pcmk__xe_get_copy(recipient, - PCMK_XA_VALUE); if (unpack_alert(recipient, recipient_entry, &max_timeout) != pcmk_rc_ok) { diff --git a/lib/common/ipc_client.c b/lib/common/ipc_client.c index 1c9cbe00c73..cc1ad7a9f1e 100644 --- a/lib/common/ipc_client.c +++ b/lib/common/ipc_client.c @@ -956,46 +956,42 @@ pcmk__connect_generic_ipc(crm_ipc_t *ipc) } void -crm_ipc_close(crm_ipc_t * client) +crm_ipc_close(crm_ipc_t *client) { - if (client) { - if (client->ipc) { - qb_ipcc_connection_t *ipc = client->ipc; - - client->ipc = NULL; - qb_ipcc_disconnect(ipc); - } + if (client == NULL) { + return; } + + g_clear_pointer(&client->ipc, qb_ipcc_disconnect); } void -crm_ipc_destroy(crm_ipc_t * client) +crm_ipc_destroy(crm_ipc_t *client) { - if (client) { - if (client->ipc && qb_ipcc_is_connected(client->ipc)) { - pcmk__notice("Destroying active %s IPC connection", - client->server_name); - /* The next line is basically unsafe - * - * If this connection was attached to mainloop and mainloop is active, - * the 'disconnected' callback will end up back here and we'll end - * up free'ing the memory twice - something that can still happen - * even without this if we destroy a connection and it closes before - * we call exit - */ - /* crm_ipc_close(client); */ - } else { - pcmk__trace("Destroying inactive %s IPC connection", - client->server_name); - } - - if (client->buffer != NULL) { - pcmk__ipc_free_client_buffer(client); - } + if (client == NULL) { + return; + } - free(client->server_name); - free(client); + if (qb_ipcc_is_connected(client->ipc)) { + pcmk__notice("Destroying active %s IPC connection", + client->server_name); + /* The next line is basically unsafe + * + * If this connection was attached to mainloop and mainloop is active, + * the 'disconnected' callback will end up back here and we'll end + * up free'ing the memory twice - something that can still happen + * even without this if we destroy a connection and it closes before + * we call exit + */ + /* crm_ipc_close(client); */ + } else { + pcmk__trace("Destroying inactive %s IPC connection", + client->server_name); } + + pcmk__ipc_free_client_buffer(client); + free(client->server_name); + free(client); } /*! @@ -1526,7 +1522,6 @@ crm_ipc_send(crm_ipc_t *client, const xmlNode *message, g_string_free(iov_buffer, TRUE); pcmk_free_ipc_event(iov); - // coverity[return_overflow] return rc; } diff --git a/lib/common/ipc_controld.c b/lib/common/ipc_controld.c index 21bfdf0ea39..00306b9ae41 100644 --- a/lib/common/ipc_controld.c +++ b/lib/common/ipc_controld.c @@ -287,7 +287,7 @@ dispatch(pcmk_ipc_api_t *api, xmlNode *reply) pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data); // Free any reply data that was allocated - if (pcmk__str_eq(value, PCMK__CONTROLD_CMD_NODES, pcmk__str_casei)) { + if (reply_data.reply_type == pcmk_controld_reply_nodes) { g_list_free_full(reply_data.data.nodes, free); } @@ -623,8 +623,11 @@ pcmk_controld_api_refresh(pcmk_ipc_api_t *api, const char *target_node, unsigned int pcmk_controld_api_replies_expected(const pcmk_ipc_api_t *api) { - struct controld_api_private_s *private = api->api_data; + struct controld_api_private_s *private = NULL; + CRM_CHECK(api != NULL, return 0); + + private = api->api_data; return private->replies_expected; } diff --git a/lib/common/mainloop.c b/lib/common/mainloop.c index 1a0e8dd4a72..7ed395a4a06 100644 --- a/lib/common/mainloop.c +++ b/lib/common/mainloop.c @@ -797,40 +797,35 @@ mainloop_gio_callback(GIOChannel *gio, GIOCondition condition, gpointer data) } static void -mainloop_gio_destroy(gpointer c) +mainloop_gio_destroy(void *c) { mainloop_io_t *client = c; - char *c_name = strdup(client->name); - /* client->source is valid but about to be destroyed (ref_count == 0) in gmain.c - * client->channel will still have ref_count > 0... should be == 1 + /* client->source is valid but about to be destroyed (ref_count == 0) in + * gmain.c. client->channel will still have ref_count > 0 (should be == 1). */ - pcmk__trace("Destroying client %s[%p]", c_name, c); + pcmk__trace("Destroying client %s[%p]", client->name, client); - if (client->ipc) { - crm_ipc_close(client->ipc); - } - - if (client->destroy_fn) { - void (*destroy_fn) (gpointer userdata) = client->destroy_fn; + // @TODO Would it be safe to call this immediately before crm_ipc_destroy()? + crm_ipc_close(client->ipc); - client->destroy_fn = NULL; - destroy_fn(client->userdata); + if (client->destroy_fn != NULL) { + client->destroy_fn(client->userdata); } - if (client->ipc) { - crm_ipc_t *ipc = client->ipc; + crm_ipc_destroy(client->ipc); - client->ipc = NULL; - crm_ipc_destroy(ipc); - } + pcmk__trace("Destroyed client %s[%p]", client->name, client); - pcmk__trace("Destroyed client %s[%p]", c_name, c); + /* This is the destructor corresponding to mainloop_add_fd(). There, + * g_io_channel_unix_new() created client->channel and added a reference to + * it, so we drop a reference here. The channel will be freed when the + * reference count drops to zero. + */ + g_io_channel_unref(client->channel); free(client->name); free(client); - - free(c_name); } /*! @@ -972,16 +967,6 @@ mainloop_add_fd(const char *name, int priority, int fd, void *userdata, (G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR), mainloop_gio_callback, client, mainloop_gio_destroy); - /* Now that mainloop now holds a reference to channel, - * thanks to g_io_add_watch_full(), drop ours from g_io_channel_unix_new(). - * - * This means that channel will be free'd by: - * g_main_context_dispatch() or g_source_remove() - * -> g_source_destroy_internal() - * -> g_source_callback_unref() - * shortly after mainloop_gio_destroy() completes - */ - g_io_channel_unref(client->channel); pcmk__trace("Added connection %d for %s[%p].%d", client->source, client->name, client, fd); } else { diff --git a/lib/common/results.c b/lib/common/results.c index e80c1811053..9c0a57b275b 100644 --- a/lib/common/results.c +++ b/lib/common/results.c @@ -1209,11 +1209,7 @@ pcmk__set_result(pcmk__action_result_t *result, int exit_status, result->exit_status = exit_status; result->execution_status = exec_status; - - if (!pcmk__str_eq(result->exit_reason, exit_reason, pcmk__str_none)) { - free(result->exit_reason); - result->exit_reason = (exit_reason == NULL)? NULL : strdup(exit_reason); - } + pcmk__str_update(&result->exit_reason, exit_reason); } @@ -1255,33 +1251,6 @@ pcmk__format_result(pcmk__action_result_t *result, int exit_status, result->exit_reason = reason; } -/*! - * \internal - * \brief Set the output of an action - * - * \param[out] result Action result to set output for - * \param[in] out Action output to set (must be dynamically - * allocated) - * \param[in] err Action error output to set (must be dynamically - * allocated) - * - * \note \p result will take ownership of \p out and \p err, so the caller - * should not free them. - */ -void -pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err) -{ - if (result == NULL) { - return; - } - - free(result->action_stdout); - result->action_stdout = out; - - free(result->action_stderr); - result->action_stderr = err; -} - /*! * \internal * \brief Clear a result's exit reason, output, and error output diff --git a/lib/fencing/st_actions.c b/lib/fencing/st_actions.c index c23d1d48a2a..8626301cd5a 100644 --- a/lib/fencing/st_actions.c +++ b/lib/fencing/st_actions.c @@ -65,10 +65,9 @@ static void log_action(stonith_action_t *action, pid_t pid); static void set_result_from_svc_action(stonith_action_t *action, svc_action_t *svc_action) { - services__copy_result(svc_action, &(action->result)); - pcmk__set_result_output(&(action->result), - services__grab_stdout(svc_action), - services__grab_stderr(svc_action)); + services__copy_result(svc_action, &action->result); + action->result.action_stdout = pcmk__str_copy(svc_action->stdout_data); + action->result.action_stderr = pcmk__str_copy(svc_action->stderr_data); } static void @@ -484,12 +483,10 @@ stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result) int exit_status = CRM_EX_OK; int execution_status = PCMK_EXEC_DONE; const char *exit_reason = NULL; - char *action_stdout = NULL; CRM_CHECK((xml != NULL) && (result != NULL), return); exit_reason = pcmk__xe_get(xml, PCMK_XA_EXIT_REASON); - action_stdout = pcmk__xe_get_copy(xml, PCMK__XA_ST_OUTPUT); // A result must include an exit status and execution status if ((pcmk__xe_get_int(xml, PCMK__XA_RC_CODE, &exit_status) != pcmk_rc_ok) @@ -515,7 +512,7 @@ stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result) } } pcmk__set_result(result, exit_status, execution_status, exit_reason); - pcmk__set_result_output(result, action_stdout, NULL); + result->action_stdout = pcmk__xe_get_copy(xml, PCMK__XA_ST_OUTPUT); } static void diff --git a/lib/lrmd/lrmd_client.c b/lib/lrmd/lrmd_client.c index d666e8a38c2..4790efbd291 100644 --- a/lib/lrmd/lrmd_client.c +++ b/lib/lrmd/lrmd_client.c @@ -179,7 +179,6 @@ lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms) { lrmd_event_data_t *event = pcmk__assert_alloc(1, sizeof(lrmd_event_data_t)); - // lrmd_event_data_t has (const char *) members that lrmd_free_event() frees event->rsc_id = pcmk__str_copy(rsc_id); event->op_type = pcmk__str_copy(task); event->interval_ms = interval_ms; @@ -187,7 +186,7 @@ lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms) } lrmd_event_data_t * -lrmd_copy_event(lrmd_event_data_t * event) +lrmd_copy_event(const lrmd_event_data_t *event) { lrmd_event_data_t *copy = NULL; @@ -195,7 +194,6 @@ lrmd_copy_event(lrmd_event_data_t * event) copy->type = event->type; - // lrmd_event_data_t has (const char *) members that lrmd_free_event() frees copy->rsc_id = pcmk__str_copy(event->rsc_id); copy->op_type = pcmk__str_copy(event->op_type); copy->user_data = pcmk__str_copy(event->user_data); @@ -231,12 +229,13 @@ lrmd_free_event(lrmd_event_data_t *event) if (event == NULL) { return; } - // @TODO Why are these const char *? - free((void *) event->rsc_id); - free((void *) event->op_type); - free((void *) event->user_data); - free((void *) event->remote_nodename); - lrmd__reset_result(event); + + free(event->rsc_id); + free(event->op_type); + free(event->user_data); + free(event->output); + free(event->remote_nodename); + free(event->exit_reason); g_clear_pointer(&event->params, g_hash_table_destroy); free(event); } @@ -279,10 +278,12 @@ lrmd_dispatch_internal(gpointer data, gpointer user_data) xmlNode *msg = data; lrmd_t *lrmd = user_data; - const char *type; + const char *op = pcmk__xe_get(msg, PCMK__XA_LRMD_OP); + const char *rsc_id = pcmk__xe_get(msg, PCMK__XA_LRMD_RSC_ID); + const char *rsc_action = pcmk__xe_get(msg, PCMK__XA_LRMD_RSC_ACTION); const char *proxy_session = pcmk__xe_get(msg, PCMK__XA_LRMD_IPC_SESSION); lrmd_private_t *native = lrmd->lrmd_private; - lrmd_event_data_t event = { 0, }; + lrmd_event_data_t *event = NULL; if (proxy_session != NULL) { if (native->proxy_callback == NULL) { @@ -299,64 +300,69 @@ lrmd_dispatch_internal(gpointer data, gpointer user_data) return; } - event.remote_nodename = native->remote_nodename; - type = pcmk__xe_get(msg, PCMK__XA_LRMD_OP); - pcmk__xe_get_int(msg, PCMK__XA_LRMD_CALLID, &event.call_id); - event.rsc_id = pcmk__xe_get(msg, PCMK__XA_LRMD_RSC_ID); + event = lrmd_new_event(rsc_id, rsc_action, 0); + event->remote_nodename = pcmk__str_copy(native->remote_nodename); + pcmk__xe_get_int(msg, PCMK__XA_LRMD_CALLID, &event->call_id); + + if (pcmk__str_eq(op, LRMD_OP_RSC_REG, pcmk__str_none)) { + event->type = lrmd_event_register; + + } else if (pcmk__str_eq(op, LRMD_OP_RSC_UNREG, pcmk__str_none)) { + event->type = lrmd_event_unregister; - if (pcmk__str_eq(type, LRMD_OP_RSC_REG, pcmk__str_none)) { - event.type = lrmd_event_register; - } else if (pcmk__str_eq(type, LRMD_OP_RSC_UNREG, pcmk__str_none)) { - event.type = lrmd_event_unregister; - } else if (pcmk__str_eq(type, LRMD_OP_RSC_EXEC, pcmk__str_none)) { + } else if (pcmk__str_eq(op, LRMD_OP_RSC_EXEC, pcmk__str_none)) { int rc = 0; int exec_time = 0; int queue_time = 0; - pcmk__xe_get_int(msg, PCMK__XA_LRMD_TIMEOUT, &event.timeout); - pcmk__xe_get_guint(msg, PCMK__XA_LRMD_RSC_INTERVAL, &event.interval_ms); + event->type = lrmd_event_exec_complete; + pcmk__xe_get_int(msg, PCMK__XA_LRMD_TIMEOUT, &event->timeout); + pcmk__xe_get_guint(msg, PCMK__XA_LRMD_RSC_INTERVAL, + &event->interval_ms); pcmk__xe_get_int(msg, PCMK__XA_LRMD_RSC_START_DELAY, - &event.start_delay); + &event->start_delay); pcmk__xe_get_int(msg, PCMK__XA_LRMD_EXEC_RC, &rc); - event.rc = (enum ocf_exitcode) rc; + event->rc = (enum ocf_exitcode) rc; - pcmk__xe_get_int(msg, PCMK__XA_LRMD_EXEC_OP_STATUS, &event.op_status); - pcmk__xe_get_int(msg, PCMK__XA_LRMD_RSC_DELETED, &event.rsc_deleted); + pcmk__xe_get_int(msg, PCMK__XA_LRMD_EXEC_OP_STATUS, &event->op_status); + pcmk__xe_get_int(msg, PCMK__XA_LRMD_RSC_DELETED, &event->rsc_deleted); - pcmk__xe_get_time(msg, PCMK__XA_LRMD_RUN_TIME, &event.t_run); - pcmk__xe_get_time(msg, PCMK__XA_LRMD_RCCHANGE_TIME, &event.t_rcchange); + pcmk__xe_get_time(msg, PCMK__XA_LRMD_RUN_TIME, &event->t_run); + pcmk__xe_get_time(msg, PCMK__XA_LRMD_RCCHANGE_TIME, &event->t_rcchange); pcmk__xe_get_int(msg, PCMK__XA_LRMD_EXEC_TIME, &exec_time); CRM_LOG_ASSERT(exec_time >= 0); - event.exec_time = QB_MAX(0, exec_time); + event->exec_time = QB_MAX(0, exec_time); pcmk__xe_get_int(msg, PCMK__XA_LRMD_QUEUE_TIME, &queue_time); - event.queue_time = QB_MAX(0, queue_time); + event->queue_time = QB_MAX(0, queue_time); - event.op_type = pcmk__xe_get(msg, PCMK__XA_LRMD_RSC_ACTION); - event.user_data = pcmk__xe_get(msg, PCMK__XA_LRMD_RSC_USERDATA_STR); - event.type = lrmd_event_exec_complete; + event->user_data = pcmk__xe_get_copy(msg, + PCMK__XA_LRMD_RSC_USERDATA_STR); - /* output and exit_reason may be freed by a callback */ - event.output = pcmk__xe_get_copy(msg, PCMK__XA_LRMD_RSC_OUTPUT); - lrmd__set_result(&event, event.rc, event.op_status, + event->output = pcmk__xe_get_copy(msg, PCMK__XA_LRMD_RSC_OUTPUT); + lrmd__set_result(event, event->rc, event->op_status, pcmk__xe_get(msg, PCMK__XA_LRMD_RSC_EXIT_REASON)); - event.params = xml2list(msg); - } else if (pcmk__str_eq(type, LRMD_OP_NEW_CLIENT, pcmk__str_none)) { - event.type = lrmd_event_new_client; - } else if (pcmk__str_eq(type, LRMD_OP_POKE, pcmk__str_none)) { - event.type = lrmd_event_poke; + event->params = xml2list(msg); + + } else if (pcmk__str_eq(op, LRMD_OP_NEW_CLIENT, pcmk__str_none)) { + event->type = lrmd_event_new_client; + + } else if (pcmk__str_eq(op, LRMD_OP_POKE, pcmk__str_none)) { + event->type = lrmd_event_poke; + } else { - return; + goto done; } - pcmk__trace("op %s notify event received", type); - native->callback(&event); + pcmk__trace("op %s notify event received", op); + + native->callback(event); - g_clear_pointer(&event.params, g_hash_table_destroy); - lrmd__reset_result(&event); +done: + lrmd_free_event(event); } // \return Always 0, to indicate that IPC mainloop source should be kept @@ -481,14 +487,19 @@ static void report_async_connection_result(lrmd_t *lrmd, int rc) { lrmd_private_t *native = lrmd->lrmd_private; + lrmd_event_data_t *event = NULL; - if (native->callback) { - lrmd_event_data_t event = { 0, }; - event.type = lrmd_event_connect; - event.remote_nodename = native->remote_nodename; - event.connection_rc = rc; - native->callback(&event); + if (native->callback == NULL) { + return; } + + event = lrmd_new_event(NULL, NULL, 0); + event->type = lrmd_event_connect; + event->connection_rc = rc; + event->remote_nodename = pcmk__str_copy(native->remote_nodename); + + native->callback(event); + lrmd_free_event(event); } static void @@ -639,6 +650,7 @@ lrmd_ipc_connection_destroy(gpointer userdata) { lrmd_t *lrmd = userdata; lrmd_private_t *native = lrmd->lrmd_private; + lrmd_event_data_t *event = NULL; switch (native->type) { case pcmk__client_ipc: @@ -657,12 +669,16 @@ lrmd_ipc_connection_destroy(gpointer userdata) native->ipc = NULL; native->source = NULL; - if (native->callback) { - lrmd_event_data_t event = { 0, }; - event.type = lrmd_event_disconnect; - event.remote_nodename = native->remote_nodename; - native->callback(&event); + if (native->callback == NULL) { + return; } + + event = lrmd_new_event(NULL, NULL, 0); + event->type = lrmd_event_disconnect; + event->remote_nodename = pcmk__str_copy(native->remote_nodename); + + native->callback(event); + lrmd_free_event(event); } /*! @@ -1088,6 +1104,7 @@ lrmd_tls_connection_destroy(gpointer userdata) { lrmd_t *lrmd = userdata; lrmd_private_t *native = lrmd->lrmd_private; + lrmd_event_data_t *event = NULL; pcmk__info("TLS connection destroyed"); @@ -1114,12 +1131,16 @@ lrmd_tls_connection_destroy(gpointer userdata) native->source = 0; native->sock = -1; - if (native->callback) { - lrmd_event_data_t event = { 0, }; - event.remote_nodename = native->remote_nodename; - event.type = lrmd_event_disconnect; - native->callback(&event); + if (native->callback == NULL) { + return; } + + event = lrmd_new_event(NULL, NULL, 0); + event->type = lrmd_event_disconnect; + event->remote_nodename = pcmk__str_copy(native->remote_nodename); + + native->callback(event); + lrmd_free_event(event); } static void @@ -2285,11 +2306,10 @@ metadata_complete(svc_action_t *action) pcmk__action_result_t result = PCMK__UNKNOWN_RESULT; services__copy_result(action, &result); - pcmk__set_result_output(&result, action->stdout_data, action->stderr_data); + result.action_stdout = pcmk__str_copy(action->stdout_data); + result.action_stderr = pcmk__str_copy(action->stderr_data); metadata_cb->callback(0, &result, metadata_cb->user_data); - result.action_stdout = NULL; // Prevent free, because action owns it - result.action_stderr = NULL; // Prevent free, because action owns it pcmk__reset_result(&result); free(metadata_cb); } @@ -2399,26 +2419,7 @@ lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, event->rc = rc; event->op_status = op_status; - - // lrmd_event_data_t has (const char *) members that lrmd_free_event() frees - pcmk__str_update((char **) &event->exit_reason, exit_reason); -} - -/*! - * \internal - * \brief Clear an executor event's exit reason, output, and error output - * - * \param[in,out] event Executor event to reset - */ -void -lrmd__reset_result(lrmd_event_data_t *event) -{ - if (event == NULL) { - return; - } - - g_clear_pointer(&event->exit_reason, free); - g_clear_pointer(&event->output, free); + pcmk__str_update(&event->exit_reason, exit_reason); } /*! diff --git a/lib/pacemaker/pcmk_agents.c b/lib/pacemaker/pcmk_agents.c index 2f56b81e998..755f97162e7 100644 --- a/lib/pacemaker/pcmk_agents.c +++ b/lib/pacemaker/pcmk_agents.c @@ -38,6 +38,7 @@ pcmk__list_alternatives(pcmk__output_t *out, const char *agent_spec) } lrmd_api_delete(lrmd_conn); + lrmd_list_freeall(list); return rc; } @@ -104,6 +105,7 @@ pcmk__list_agents(pcmk__output_t *out, char *agent_spec) } lrmd_api_delete(lrmd_conn); + lrmd_list_freeall(list); return rc; } @@ -156,6 +158,7 @@ pcmk__list_providers(pcmk__output_t *out, const char *agent_spec) } lrmd_api_delete(lrmd_conn); + lrmd_list_freeall(list); return rc; } @@ -203,6 +206,7 @@ pcmk__list_standards(pcmk__output_t *out) } lrmd_api_delete(lrmd_conn); + lrmd_list_freeall(list); return rc; } diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c index 4ef60985f98..49f92f96bd6 100644 --- a/lib/pengine/bundle.c +++ b/lib/pengine/bundle.c @@ -52,7 +52,6 @@ typedef struct { int promoted_max; int nreplicas; int nreplicas_per_host; - char *prefix; char *image; const char *ip_last; char *host_network; @@ -275,35 +274,34 @@ next_ip(const char *last_ip) } static void -allocate_ip(pe__bundle_variant_data_t *data, pcmk__bundle_replica_t *replica, +allocate_ip(pcmk_resource_t *parent, pcmk__bundle_replica_t *replica, GString *buffer) { - if(data->ip_range_start == NULL) { - return; + pe__bundle_variant_data_t *bundle_data = NULL; - } else if(data->ip_last) { - replica->ipaddr = next_ip(data->ip_last); + get_bundle_variant_data(bundle_data, parent); - } else { - replica->ipaddr = strdup(data->ip_range_start); + if (bundle_data->ip_range_start == NULL) { + return; } - data->ip_last = replica->ipaddr; - - if ((data->agent_type != PE__CONTAINER_AGENT_DOCKER) - && (data->agent_type != PE__CONTAINER_AGENT_PODMAN)) { + if (bundle_data->ip_last != NULL) { + replica->ipaddr = next_ip(bundle_data->ip_last); - return; + } else { + replica->ipaddr = pcmk__str_copy(bundle_data->ip_range_start); } - if (data->add_host) { - g_string_append_printf(buffer, " --add-host=%s-%d:%s", data->prefix, + bundle_data->ip_last = replica->ipaddr; + + if (bundle_data->add_host) { + g_string_append_printf(buffer, " --add-host=%s-%d:%s", parent->id, replica->offset, replica->ipaddr); return; } g_string_append_printf(buffer, " --hosts-entry=%s=%s-%d", replica->ipaddr, - data->prefix, replica->offset); + parent->id, replica->offset); } static xmlNode * @@ -319,66 +317,36 @@ create_resource(const char *name, const char *provider, const char *kind) return rsc; } -/*! - * \internal - * \brief Check whether cluster can manage resource inside container - * - * \param[in,out] data Container variant data - * - * \return TRUE if networking configuration is acceptable, FALSE otherwise - * - * \note The resource is manageable if an IP range or control port has been - * specified. If a control port is used without an IP range, replicas per - * host must be 1. - */ -static bool -valid_network(pe__bundle_variant_data_t *data) -{ - if(data->ip_range_start) { - return TRUE; - } - if(data->control_port) { - if(data->nreplicas_per_host > 1) { - pcmk__config_err("Specifying the '" PCMK_XA_CONTROL_PORT "' for %s " - "requires '" PCMK_XA_REPLICAS_PER_HOST "=1'", - data->prefix); - data->nreplicas_per_host = 1; - // @TODO to be sure: - // pcmk__clear_rsc_flags(rsc, pcmk__rsc_unique); - } - return TRUE; - } - return FALSE; -} - static int -create_ip_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, - pcmk__bundle_replica_t *replica) +create_ip_resource(pcmk_resource_t *parent, pcmk__bundle_replica_t *replica) { char *id = NULL; xmlNode *xml_ip = NULL; xmlNode *xml_obj = NULL; int rc = pcmk_rc_ok; + pe__bundle_variant_data_t *bundle_data = NULL; + + get_bundle_variant_data(bundle_data, parent); - if (data->ip_range_start == NULL) { + if (bundle_data->ip_range_start == NULL) { goto done; } - id = pcmk__assert_asprintf("%s-ip-%s", data->prefix, replica->ipaddr); + id = pcmk__assert_asprintf("%s-ip-%s", parent->id, replica->ipaddr); pcmk__xml_sanitize_id(id); xml_ip = create_resource(id, "heartbeat", "IPaddr2"); xml_obj = pcmk__xe_create(xml_ip, PCMK_XE_INSTANCE_ATTRIBUTES); - pcmk__xe_set_id(xml_obj, "%s-attributes-%d", data->prefix, replica->offset); + pcmk__xe_set_id(xml_obj, "%s-attributes-%d", parent->id, replica->offset); crm_create_nvpair_xml(xml_obj, NULL, "ip", replica->ipaddr); - if (data->host_network != NULL) { - crm_create_nvpair_xml(xml_obj, NULL, "nic", data->host_network); + if (bundle_data->host_network != NULL) { + crm_create_nvpair_xml(xml_obj, NULL, "nic", bundle_data->host_network); } crm_create_nvpair_xml(xml_obj, NULL, "cidr_netmask", - pcmk__s(data->host_netmask, "32")); + pcmk__s(bundle_data->host_netmask, "32")); xml_obj = pcmk__xe_create(xml_ip, PCMK_XE_OPERATIONS); crm_create_op_xml(xml_obj, id, PCMK_ACTION_MONITOR, "60s", NULL); @@ -413,7 +381,6 @@ container_agent_str(enum pe__container_agent t) static int create_container_resource(pcmk_resource_t *parent, - const pe__bundle_variant_data_t *data, pcmk__bundle_replica_t *replica) { char *id = NULL; @@ -423,31 +390,27 @@ create_container_resource(pcmk_resource_t *parent, GString *buffer = NULL; GString *dbuffer = NULL; int rc = pcmk_rc_ok; + const pe__bundle_variant_data_t *bundle_data = NULL; - if ((data->agent_type != PE__CONTAINER_AGENT_DOCKER) - && (data->agent_type != PE__CONTAINER_AGENT_PODMAN)) { + get_bundle_variant_data(bundle_data, parent); - rc = pcmk_rc_unpack_error; - goto done; - } - - agent_str = container_agent_str(data->agent_type); + agent_str = container_agent_str(bundle_data->agent_type); buffer = g_string_sized_new(4096); - id = pcmk__assert_asprintf("%s-%s-%d", data->prefix, agent_str, + id = pcmk__assert_asprintf("%s-%s-%d", parent->id, agent_str, replica->offset); pcmk__xml_sanitize_id(id); xml_container = create_resource(id, "heartbeat", agent_str); xml_obj = pcmk__xe_create(xml_container, PCMK_XE_INSTANCE_ATTRIBUTES); - pcmk__xe_set_id(xml_obj, "%s-attributes-%d", data->prefix, replica->offset); + pcmk__xe_set_id(xml_obj, "%s-attributes-%d", parent->id, replica->offset); - crm_create_nvpair_xml(xml_obj, NULL, "image", data->image); + crm_create_nvpair_xml(xml_obj, NULL, "image", bundle_data->image); crm_create_nvpair_xml(xml_obj, NULL, "allow_pull", PCMK_VALUE_TRUE); crm_create_nvpair_xml(xml_obj, NULL, "force_kill", PCMK_VALUE_FALSE); crm_create_nvpair_xml(xml_obj, NULL, "reuse", PCMK_VALUE_FALSE); - if (data->agent_type == PE__CONTAINER_AGENT_DOCKER) { + if (bundle_data->agent_type == PE__CONTAINER_AGENT_DOCKER) { g_string_append(buffer, " --restart=no"); } @@ -456,32 +419,33 @@ create_container_resource(pcmk_resource_t *parent, * this makes applications happy who need their hostname to match the IP * they bind to. */ - if (data->ip_range_start != NULL) { - g_string_append_printf(buffer, " -h %s-%d", data->prefix, + if (bundle_data->ip_range_start != NULL) { + g_string_append_printf(buffer, " -h %s-%d", parent->id, replica->offset); } g_string_append(buffer, " -e PCMK_stderr=1"); - if (data->container_network != NULL) { - pcmk__g_strcat(buffer, " --net=", data->container_network, NULL); + if (bundle_data->container_network != NULL) { + pcmk__g_strcat(buffer, " --net=", bundle_data->container_network, NULL); } - if (data->control_port != NULL) { + if (bundle_data->control_port != NULL) { pcmk__g_strcat(buffer, " -e PCMK_" PCMK__ENV_REMOTE_PORT "=", - data->control_port, NULL); + bundle_data->control_port, NULL); + } else { g_string_append_printf(buffer, " -e PCMK_" PCMK__ENV_REMOTE_PORT "=%d", DEFAULT_REMOTE_PORT); } - for (GList *iter = data->mounts; iter != NULL; iter = iter->next) { - pe__bundle_mount_t *mount = (pe__bundle_mount_t *) iter->data; + for (GList *iter = bundle_data->mounts; iter != NULL; iter = iter->next) { + pe__bundle_mount_t *mount = iter->data; char *source = NULL; if (pcmk__is_set(mount->flags, pe__bundle_mount_subdir)) { source = pcmk__assert_asprintf("%s/%s-%d", mount->source, - data->prefix, replica->offset); + parent->id, replica->offset); pcmk__add_separated_word(&dbuffer, 1024, source, ","); } @@ -495,15 +459,15 @@ create_container_resource(pcmk_resource_t *parent, free(source); } - for (GList *iter = data->ports; iter != NULL; iter = iter->next) { - pe__bundle_port_t *port = (pe__bundle_port_t *) iter->data; + for (GList *iter = bundle_data->ports; iter != NULL; iter = iter->next) { + pe__bundle_port_t *port = iter->data; if (replica->ipaddr != NULL) { pcmk__g_strcat(buffer, " -p ", replica->ipaddr, ":", port->source, ":", port->target, NULL); - } else if (!pcmk__str_eq(data->container_network, PCMK_VALUE_HOST, - pcmk__str_none)) { + } else if (!pcmk__str_eq(bundle_data->container_network, + PCMK_VALUE_HOST, pcmk__str_none)) { // No need to do port mapping if net == host pcmk__g_strcat(buffer, " -p ", port->source, ":", port->target, @@ -515,36 +479,36 @@ create_container_resource(pcmk_resource_t *parent, * it would cause restarts during rolling upgrades. * * In a previous version of the container resource creation logic, if - * data->launcher_options is not NULL, we append - * (" %s", data->launcher_options) even if data->launcher_options is an - * empty string. Likewise for data->container_host_options. Using + * bundle_data->launcher_options is not NULL, we append + * (" %s", bundle_data->launcher_options) even if + * bundle_data->launcher_options is an empty string. Likewise for + * bundle_data->container_host_options. Using * - * pcmk__add_word(buffer, 0, data->launcher_options) + * pcmk__add_word(buffer, 0, bundle_data->launcher_options) * * removes that extra trailing space, causing a resource definition change. */ - if (data->launcher_options != NULL) { - pcmk__g_strcat(buffer, " ", data->launcher_options, NULL); + if (bundle_data->launcher_options != NULL) { + pcmk__g_strcat(buffer, " ", bundle_data->launcher_options, NULL); } - if (data->container_host_options != NULL) { - pcmk__g_strcat(buffer, " ", data->container_host_options, NULL); + if (bundle_data->container_host_options != NULL) { + pcmk__g_strcat(buffer, " ", bundle_data->container_host_options, NULL); } - crm_create_nvpair_xml(xml_obj, NULL, "run_opts", - (const char *) buffer->str); + crm_create_nvpair_xml(xml_obj, NULL, "run_opts", buffer->str); g_string_free(buffer, TRUE); crm_create_nvpair_xml(xml_obj, NULL, "mount_points", - (dbuffer != NULL)? (const char *) dbuffer->str : ""); + (dbuffer != NULL)? dbuffer->str : ""); if (dbuffer != NULL) { g_string_free(dbuffer, TRUE); } if (replica->child != NULL) { - if (data->container_command != NULL) { + if (bundle_data->container_command != NULL) { crm_create_nvpair_xml(xml_obj, NULL, "run_cmd", - data->container_command); + bundle_data->container_command); } else { crm_create_nvpair_xml(xml_obj, NULL, "run_cmd", SBIN_DIR "/" PCMK__SERVER_REMOTED); @@ -563,16 +527,16 @@ create_container_resource(pcmk_resource_t *parent, * However, this would probably be better done via ACLs as with other * Pacemaker Remote nodes. */ - } else if ((child != NULL) && data->untrusted) { + } else if ((child != NULL) && bundle_data->untrusted) { crm_create_nvpair_xml(xml_obj, NULL, "run_cmd", CRM_DAEMON_DIR "/" PCMK__SERVER_EXECD); crm_create_nvpair_xml(xml_obj, NULL, "monitor_cmd", CRM_DAEMON_DIR "/pacemaker/cts-exec-helper -c poke"); #endif } else { - if (data->container_command != NULL) { + if (bundle_data->container_command != NULL) { crm_create_nvpair_xml(xml_obj, NULL, "run_cmd", - data->container_command); + bundle_data->container_command); } /* TODO: Allow users to specify their own? @@ -625,10 +589,9 @@ disallow_node(pcmk_resource_t *rsc, const char *uname) } static int -create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, - pcmk__bundle_replica_t *replica) +create_remote_resource(pcmk_resource_t *parent, pcmk__bundle_replica_t *replica) { - GHashTableIter gIter; + GHashTableIter iter; pcmk_node_t *node = NULL; pcmk_node_t *copy = NULL; xmlNode *xml_remote = NULL; @@ -637,12 +600,15 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, const char *connect_name = NULL; pcmk_scheduler_t *scheduler = parent->priv->scheduler; int rc = pcmk_rc_ok; + pe__bundle_variant_data_t *bundle_data = NULL; + + get_bundle_variant_data(bundle_data, parent); - if ((replica->child == NULL) || !valid_network(data)) { + if (replica->child == NULL) { goto done; } - id = pcmk__assert_asprintf("%s-%d", data->prefix, replica->offset); + id = pcmk__assert_asprintf("%s-%d", parent->id, replica->offset); if (pe_find_resource(scheduler->priv->resources, id) != NULL) { free(id); @@ -666,10 +632,10 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, * that the bundle node is fenced by recovering the container, and that * remote should be ordered relative to the container. */ - if (data->control_port != NULL) { + if (bundle_data->control_port != NULL) { xml_remote = pe_create_remote_xml(NULL, id, replica->container->id, NULL, NULL, NULL, connect_name, - data->control_port); + bundle_data->control_port); } else { char *port_s = pcmk__itoa(DEFAULT_REMOTE_PORT); @@ -752,8 +718,8 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, // Make Coverity happy pcmk__assert(replica->remote != NULL); - g_hash_table_iter_init(&gIter, replica->remote->priv->allowed_nodes); - while (g_hash_table_iter_next(&gIter, NULL, (void **)&node)) { + g_hash_table_iter_init(&iter, replica->remote->priv->allowed_nodes); + while (g_hash_table_iter_next(&iter, NULL, (void **) &node)) { if (pcmk__is_pacemaker_remote_node(node)) { // Remote resources can only run on 'normal' cluster node node->assign->score = -PCMK_SCORE_INFINITY; @@ -790,22 +756,21 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, static int create_replica_resources(pcmk_resource_t *parent, - pe__bundle_variant_data_t *data, pcmk__bundle_replica_t *replica) { int rc = pcmk_rc_ok; - rc = create_container_resource(parent, data, replica); + rc = create_container_resource(parent, replica); if (rc != pcmk_rc_ok) { return rc; } - rc = create_ip_resource(parent, data, replica); + rc = create_ip_resource(parent, replica); if (rc != pcmk_rc_ok) { return rc; } - rc = create_remote_resource(parent, data, replica); + rc = create_remote_resource(parent, replica); if (rc != pcmk_rc_ok) { return rc; } @@ -825,6 +790,31 @@ create_replica_resources(pcmk_resource_t *parent, */ pcmk__set_rsc_flags(replica->remote, pcmk__rsc_remote_nesting_allowed); } + + /* Utilization needs special handling for bundles. It makes no sense for the + * inner primitive to have utilization, because it is tied one-to-one to the + * guest node created by the container resource -- and there's no way to set + * capacities for that guest node anyway. + * + * What the user really wants is to configure utilization for the container. + * However, the schema only allows utilization for primitives, and the + * container resource is implicit anyway, so the user can *only* configure + * utilization for the inner primitive. If they do, move the primitive's + * utilization values to the container. + * + * @TODO This means that bundles without an inner primitive can't have + * utilization. An alternative might be to allow utilization values in the + * top-level bundle XML in the schema, and copy those to each container. + */ + if (replica->child != NULL) { + GHashTable *empty = replica->container->priv->utilization; + + replica->container->priv->utilization = + replica->child->priv->utilization; + + replica->child->priv->utilization = empty; + } + return rc; } @@ -873,9 +863,8 @@ replica_for_remote(pcmk_resource_t *remote) } get_bundle_variant_data(bundle_data, top); - for (GList *gIter = bundle_data->replicas; gIter != NULL; - gIter = gIter->next) { - pcmk__bundle_replica_t *replica = gIter->data; + for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { + pcmk__bundle_replica_t *replica = iter->data; if (replica->remote == remote) { return replica; @@ -944,370 +933,519 @@ pe__add_bundle_remote_name(pcmk_resource_t *rsc, xmlNode *xml, return node->priv->name; } -#define pe__set_bundle_mount_flags(mount_xml, flags, flags_to_set) do { \ - flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \ - "Bundle mount", pcmk__xe_id(mount_xml), \ - flags, (flags_to_set), #flags_to_set); \ - } while (0) - -bool -pe__unpack_bundle(pcmk_resource_t *rsc) +/*! + * \internal + * \brief Get container XML element from a bundle resource and set agent type + * + * On success, this sets the \c agent_type field of the resource's bundle + * private data. + * + * \param[in,out] rsc Bundle resource + * + * \return Child XML element for container within rsc->priv->xml + */ +static xmlNode * +get_container_xml(pcmk_resource_t *rsc) { - const char *value = NULL; - xmlNode *xml_obj = NULL; - const xmlNode *xml_child = NULL; - xmlNode *xml_resource = NULL; + xmlNode *xml = NULL; pe__bundle_variant_data_t *bundle_data = NULL; - bool need_log_mount = TRUE; - pcmk__assert(rsc != NULL); - pcmk__rsc_trace(rsc, "Processing resource %s...", rsc->id); - - bundle_data = pcmk__assert_alloc(1, sizeof(pe__bundle_variant_data_t)); - rsc->priv->variant_opaque = bundle_data; - bundle_data->prefix = strdup(rsc->id); + get_bundle_variant_data(bundle_data, rsc); - xml_obj = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_DOCKER, NULL, - NULL); - if (xml_obj != NULL) { + xml = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_DOCKER, NULL, NULL); + if (xml != NULL) { bundle_data->agent_type = PE__CONTAINER_AGENT_DOCKER; + return xml; } - if (xml_obj == NULL) { - xml_obj = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_PODMAN, NULL, - NULL); - if (xml_obj != NULL) { - bundle_data->agent_type = PE__CONTAINER_AGENT_PODMAN; - } + xml = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_PODMAN, NULL, NULL); + if (xml != NULL) { + bundle_data->agent_type = PE__CONTAINER_AGENT_PODMAN; + return xml; } - if (xml_obj == NULL) { - return FALSE; + return NULL; +} + +/*! + * \internal + * \brief Unpack a bundle resource's container child into bundle private data + * + * This does not create or unpack a container resource. + * + * \param[in,out] rsc Bundle resource + * + * \return Standard Pacemaker return code + */ +static int +unpack_bundle_container(pcmk_resource_t *rsc) +{ + xmlNode *xml = NULL; + pe__bundle_variant_data_t *bundle_data = NULL; + const char *value = NULL; + + xml = get_container_xml(rsc); + if (xml == NULL) { + return pcmk_rc_unpack_error; } + get_bundle_variant_data(bundle_data, rsc); + // Use 0 for default, minimum, and invalid PCMK_XA_PROMOTED_MAX - value = pcmk__xe_get(xml_obj, PCMK_XA_PROMOTED_MAX); + value = pcmk__xe_get(xml, PCMK_XA_PROMOTED_MAX); pcmk__scan_min_int(value, &bundle_data->promoted_max, 0); - /* Default replicas to PCMK_XA_PROMOTED_MAX if it was specified and 1 - * otherwise - */ - value = pcmk__xe_get(xml_obj, PCMK_XA_REPLICAS); + // Default nreplicas to PCMK_XA_PROMOTED_MAX if specified or 1 otherwise + value = pcmk__xe_get(xml, PCMK_XA_REPLICAS); + if ((value == NULL) && (bundle_data->promoted_max > 0)) { bundle_data->nreplicas = bundle_data->promoted_max; + } else { pcmk__scan_min_int(value, &bundle_data->nreplicas, 1); } - /* - * Communication between containers on the same host via the - * floating IPs only works if the container is started with: + /* Communication between containers on the same host via the floating IPs + * works only if the container is started with: * --userland-proxy=false --ip-masq=false */ - value = pcmk__xe_get(xml_obj, PCMK_XA_REPLICAS_PER_HOST); + value = pcmk__xe_get(xml, PCMK_XA_REPLICAS_PER_HOST); pcmk__scan_min_int(value, &bundle_data->nreplicas_per_host, 1); + if (bundle_data->nreplicas_per_host == 1) { pcmk__clear_rsc_flags(rsc, pcmk__rsc_unique); } - bundle_data->container_command = pcmk__xe_get_copy(xml_obj, + bundle_data->container_command = pcmk__xe_get_copy(xml, PCMK_XA_RUN_COMMAND); - bundle_data->launcher_options = pcmk__xe_get_copy(xml_obj, PCMK_XA_OPTIONS); - bundle_data->image = pcmk__xe_get_copy(xml_obj, PCMK_XA_IMAGE); - bundle_data->container_network = pcmk__xe_get_copy(xml_obj, - PCMK_XA_NETWORK); - - xml_obj = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_NETWORK, NULL, - NULL); - if(xml_obj) { - bundle_data->ip_range_start = pcmk__xe_get_copy(xml_obj, - PCMK_XA_IP_RANGE_START); - bundle_data->host_netmask = pcmk__xe_get_copy(xml_obj, - PCMK_XA_HOST_NETMASK); - bundle_data->host_network = pcmk__xe_get_copy(xml_obj, - PCMK_XA_HOST_INTERFACE); - bundle_data->control_port = pcmk__xe_get_copy(xml_obj, - PCMK_XA_CONTROL_PORT); - - value = pcmk__xe_get(xml_obj, PCMK_XA_ADD_HOST); - if ((value == NULL) - || (pcmk__parse_bool(value, - &bundle_data->add_host) != pcmk_rc_ok)) { - - // Default to true if unset or invaid - bundle_data->add_host = true; - } + bundle_data->launcher_options = pcmk__xe_get_copy(xml, PCMK_XA_OPTIONS); + bundle_data->image = pcmk__xe_get_copy(xml, PCMK_XA_IMAGE); + bundle_data->container_network = pcmk__xe_get_copy(xml, PCMK_XA_NETWORK); + return pcmk_rc_ok; +} - for (xml_child = pcmk__xe_first_child(xml_obj, PCMK_XE_PORT_MAPPING, - NULL, NULL); - xml_child != NULL; - xml_child = pcmk__xe_next(xml_child, PCMK_XE_PORT_MAPPING)) { +/*! + * \internal + * \brief Unpack a bundle resource's network child into bundle private data + * + * This does not create or unpack an IP resource. + * + * \param[in,out] rsc Bundle resource + */ +static void +unpack_bundle_network(pcmk_resource_t *rsc) +{ + xmlNode *xml = NULL; + pe__bundle_variant_data_t *bundle_data = NULL; + const char *value = NULL; - pe__bundle_port_t *port = - pcmk__assert_alloc(1, sizeof(pe__bundle_port_t)); + xml = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_NETWORK, NULL, NULL); + if (xml == NULL) { + return; + } - port->source = pcmk__xe_get_copy(xml_child, PCMK_XA_PORT); + get_bundle_variant_data(bundle_data, rsc); - if(port->source == NULL) { - port->source = pcmk__xe_get_copy(xml_child, PCMK_XA_RANGE); - } else { - port->target = pcmk__xe_get_copy(xml_child, - PCMK_XA_INTERNAL_PORT); - } + bundle_data->ip_range_start = pcmk__xe_get_copy(xml, + PCMK_XA_IP_RANGE_START); + bundle_data->host_netmask = pcmk__xe_get_copy(xml, PCMK_XA_HOST_NETMASK); + bundle_data->host_network = pcmk__xe_get_copy(xml, PCMK_XA_HOST_INTERFACE); + bundle_data->control_port = pcmk__xe_get_copy(xml, PCMK_XA_CONTROL_PORT); - if(port->source != NULL && strlen(port->source) > 0) { - if(port->target == NULL) { - port->target = strdup(port->source); - } - bundle_data->ports = g_list_append(bundle_data->ports, port); + value = pcmk__xe_get(xml, PCMK_XA_ADD_HOST); + if ((value == NULL) + || (pcmk__parse_bool(value, &bundle_data->add_host) != pcmk_rc_ok)) { - } else { - pcmk__config_err("Invalid " PCMK_XA_PORT " directive %s", - pcmk__xe_id(xml_child)); - port_free(port); - } - } + // Default to true if unset or invaid + bundle_data->add_host = true; } - xml_obj = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_STORAGE, NULL, - NULL); - for (xml_child = pcmk__xe_first_child(xml_obj, PCMK_XE_STORAGE_MAPPING, - NULL, NULL); - xml_child != NULL; - xml_child = pcmk__xe_next(xml_child, PCMK_XE_STORAGE_MAPPING)) { + for (const xmlNode *mapping = pcmk__xe_first_child(xml, + PCMK_XE_PORT_MAPPING, + NULL, NULL); + mapping != NULL; + mapping = pcmk__xe_next(mapping, PCMK_XE_PORT_MAPPING)) { - const char *source = pcmk__xe_get(xml_child, PCMK_XA_SOURCE_DIR); - const char *target = pcmk__xe_get(xml_child, PCMK_XA_TARGET_DIR); - const char *options = pcmk__xe_get(xml_child, PCMK_XA_OPTIONS); - int flags = pe__bundle_mount_none; + pe__bundle_port_t *port = pcmk__assert_alloc(1, + sizeof(pe__bundle_port_t)); - if (source == NULL) { - source = pcmk__xe_get(xml_child, PCMK_XA_SOURCE_DIR_ROOT); - pe__set_bundle_mount_flags(xml_child, flags, - pe__bundle_mount_subdir); - } + port->source = pcmk__xe_get_copy(mapping, PCMK_XA_PORT); + + if (port->source == NULL) { + port->source = pcmk__xe_get_copy(mapping, PCMK_XA_RANGE); - if (source && target) { - mount_add(bundle_data, source, target, options, flags); - if (strcmp(target, "/var/log") == 0) { - need_log_mount = FALSE; - } } else { - pcmk__config_err("Invalid mount directive %s", - pcmk__xe_id(xml_child)); + port->target = pcmk__xe_get_copy(mapping, PCMK_XA_INTERNAL_PORT); } + + if (pcmk__str_empty(port->source)) { + pcmk__config_err("Invalid " PCMK_XA_PORT " directive %s", + pcmk__xe_id(mapping)); + port_free(port); + return; + } + + if (port->target == NULL) { + port->target = pcmk__str_copy(port->source); + } + + bundle_data->ports = g_list_append(bundle_data->ports, port); + } +} + +/*! + * \internal + * \brief Unpack a bundle resource's storage child into bundle private data + * + * \param[in,out] rsc Bundle resource + * + * \return \c true if a mount with target \c "/var/log" was unpacked, or + * \c false otherwise + */ +static bool +unpack_bundle_storage(pcmk_resource_t *rsc) +{ + xmlNode *xml = NULL; + pe__bundle_variant_data_t *bundle_data = NULL; + bool have_log_mount = false; + + xml = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_STORAGE, NULL, NULL); + if (xml == NULL) { + return false; } - xml_obj = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_PRIMITIVE, NULL, - NULL); - if (xml_obj && valid_network(bundle_data)) { - const char *suffix = NULL; - char *value = NULL; - xmlNode *xml_set = NULL; + get_bundle_variant_data(bundle_data, rsc); - xml_resource = pcmk__xe_create(NULL, PCMK_XE_CLONE); + for (const xmlNode *mapping = pcmk__xe_first_child(xml, + PCMK_XE_STORAGE_MAPPING, + NULL, NULL); + mapping != NULL; + mapping = pcmk__xe_next(mapping, PCMK_XE_STORAGE_MAPPING)) { - /* @COMPAT We no longer use the tag, but we need to keep it as - * part of the resource name, so that bundles don't restart in a rolling - * upgrade. (It also avoids needing to change regression tests.) - */ - suffix = (const char *) xml_resource->name; - if (bundle_data->promoted_max > 0) { - suffix = "master"; + const char *source = pcmk__xe_get(mapping, PCMK_XA_SOURCE_DIR); + const char *target = pcmk__xe_get(mapping, PCMK_XA_TARGET_DIR); + const char *options = pcmk__xe_get(mapping, PCMK_XA_OPTIONS); + uint32_t flags = pe__bundle_mount_none; + + if (source == NULL) { + source = pcmk__xe_get(mapping, PCMK_XA_SOURCE_DIR_ROOT); + flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, + "Bundle mount", pcmk__xe_id(mapping), + flags, pe__bundle_mount_subdir, + "pe__bundle_mount_subdir"); } - pcmk__xe_set_id(xml_resource, "%s-%s", bundle_data->prefix, suffix); + if ((source == NULL) || (target == NULL)) { + pcmk__config_err("Invalid mount directive %s", + pcmk__xe_id(mapping)); + continue; + } + + mount_add(bundle_data, source, target, options, flags); + if (pcmk__str_eq(target, "/var/log", pcmk__str_none)) { + have_log_mount = true; + } + } + + return have_log_mount; +} - xml_set = pcmk__xe_create(xml_resource, PCMK_XE_META_ATTRIBUTES); - pcmk__xe_set_id(xml_set, "%s-%s-meta", - bundle_data->prefix, xml_resource->name); +/*! + * \internal + * \brief Validate a bundle's networking configuration for running a primitive + * + * The networking configuration is considered valid if an IP range or control + * port has been specified. If a control port is used without an IP range, + * replicas per host must be 1. + * + * \param[in,out] rsc Bundle resource + * + * \return \c true if the configuration is valid, or \c false otherwise + */ +static bool +valid_network_for_primitive(pcmk_resource_t *rsc) +{ + pe__bundle_variant_data_t *bundle_data = NULL; - crm_create_nvpair_xml(xml_set, NULL, - PCMK_META_ORDERED, PCMK_VALUE_TRUE); + get_bundle_variant_data(bundle_data, rsc); - value = pcmk__itoa(bundle_data->nreplicas); - crm_create_nvpair_xml(xml_set, NULL, PCMK_META_CLONE_MAX, value); - free(value); + if (bundle_data->ip_range_start != NULL) { + return true; + } - value = pcmk__itoa(bundle_data->nreplicas_per_host); - crm_create_nvpair_xml(xml_set, NULL, PCMK_META_CLONE_NODE_MAX, value); - free(value); + if (bundle_data->control_port == NULL) { + return false; + } - crm_create_nvpair_xml(xml_set, NULL, PCMK_META_GLOBALLY_UNIQUE, - pcmk__btoa(bundle_data->nreplicas_per_host > 1)); + if (bundle_data->nreplicas_per_host > 1) { + pcmk__config_warn("Using " PCMK_XA_REPLICAS_PER_HOST "=1 for %s " + "because specifying " PCMK_XA_CONTROL_PORT " " + "requires it", rsc->id); + bundle_data->nreplicas_per_host = 1; + pcmk__clear_rsc_flags(rsc, pcmk__rsc_unique); + } - if (bundle_data->promoted_max) { - crm_create_nvpair_xml(xml_set, NULL, - PCMK_META_PROMOTABLE, PCMK_VALUE_TRUE); + return true; +} - value = pcmk__itoa(bundle_data->promoted_max); - crm_create_nvpair_xml(xml_set, NULL, PCMK_META_PROMOTED_MAX, value); - free(value); - } +/*! + * \internal + * \brief Unpack a bundle resource's primitive child + * + * If a primitive child is found, this creates a \c PCMK_XE_CLONE element + * containing a copy of the primitive element and appropriate options. This does + * not unpack the created element. + * + * \param[in,out] rsc Bundle resource + * \param[out] clone_xml Where to store newly allocated \c PCMK_XE_CLONE + * + * \return Standard Pacemaker return code + * + * \note The caller is responsible for freeing \p *clone_xml using + * \c pcmk__xml_free(). + */ +static int +unpack_bundle_primitive(pcmk_resource_t *rsc, xmlNode **clone_xml) +{ + xmlNode *primitive_xml = NULL; + pe__bundle_variant_data_t *bundle_data = NULL; + const char *suffix = NULL; + xmlNode *meta = NULL; + xmlNode *nvpair = NULL; - //pcmk__xe_set(xml_obj, PCMK_XA_ID, bundle_data->prefix); - pcmk__xml_copy(xml_resource, xml_obj); + primitive_xml = pcmk__xe_first_child(rsc->priv->xml, PCMK_XE_PRIMITIVE, + NULL, NULL); + if (primitive_xml == NULL) { + return pcmk_rc_ok; + } - } else if(xml_obj) { + if (!valid_network_for_primitive(rsc)) { pcmk__config_err("Cannot control %s inside %s without either " PCMK_XA_IP_RANGE_START " or " PCMK_XA_CONTROL_PORT, - rsc->id, pcmk__xe_id(xml_obj)); - return FALSE; + rsc->id, pcmk__xe_id(primitive_xml)); + return pcmk_rc_unpack_error; } - if(xml_resource) { - int lpc = 0; - GList *childIter = NULL; - pe__bundle_port_t *port = NULL; - GString *buffer = NULL; - int rc = pe__unpack_resource(xml_resource, &bundle_data->child, rsc, - rsc->priv->scheduler); + get_bundle_variant_data(bundle_data, rsc); - pcmk__xml_free(xml_resource); + *clone_xml = pcmk__xe_create(NULL, PCMK_XE_CLONE); - if (rc != pcmk_rc_ok) { - return FALSE; - } + /* @COMPAT We no longer use the tag, but we need to keep it as part + * of the resource name, so that bundles don't restart in a rolling upgrade. + * (It also avoids needing to change regression tests.) + */ + suffix = (bundle_data->promoted_max > 0)? "master" : PCMK_XE_CLONE; + pcmk__xe_set_id(*clone_xml, "%s-%s", rsc->id, suffix); - /* Currently, we always map the default authentication key location - * into the same location inside the container. - * - * Ideally, we would respect the host's PCMK_authkey_location, but: - * - it may be different on different nodes; - * - the actual connection will do extra checking to make sure the key - * file exists and is readable, that we can't do here on the DC - * - tools such as crm_resource and crm_simulate may not have the same - * environment variables as the cluster, causing operation digests to - * differ - * - * Always using the default location inside the container is fine, - * because we control the pacemaker_remote environment, and it avoids - * having to pass another environment variable to the container. + meta = pcmk__xe_create(*clone_xml, PCMK_XE_META_ATTRIBUTES); + pcmk__xe_set_id(meta, "%s-%s-meta", rsc->id, (*clone_xml)->name); + + crm_create_nvpair_xml(meta, NULL, PCMK_META_ORDERED, PCMK_VALUE_TRUE); + + nvpair = crm_create_nvpair_xml(meta, NULL, PCMK_META_CLONE_MAX, NULL); + pcmk__xe_set_int(nvpair, PCMK_XA_VALUE, bundle_data->nreplicas); + + nvpair = crm_create_nvpair_xml(meta, NULL, PCMK_META_CLONE_NODE_MAX, NULL); + pcmk__xe_set_int(nvpair, PCMK_XA_VALUE, bundle_data->nreplicas_per_host); + + nvpair = crm_create_nvpair_xml(meta, NULL, PCMK_META_GLOBALLY_UNIQUE, NULL); + pcmk__xe_set_bool(nvpair, PCMK_XA_VALUE, + pcmk__is_set(rsc->flags, pcmk__rsc_unique)); + + if (bundle_data->promoted_max != 0) { + crm_create_nvpair_xml(meta, NULL, PCMK_META_PROMOTABLE, + PCMK_VALUE_TRUE); + + nvpair = crm_create_nvpair_xml(meta, NULL, PCMK_META_PROMOTED_MAX, + NULL); + pcmk__xe_set_int(nvpair, PCMK_XA_VALUE, bundle_data->promoted_max); + } + + //pcmk__xe_set(primitive_xml, PCMK_XA_ID, rsc->id); + pcmk__xml_copy(*clone_xml, primitive_xml); + + return pcmk_rc_ok; +} + +static int +create_child_resource(pcmk_resource_t *rsc, xmlNode *clone_xml, + bool have_log_mount) +{ + int offset = 0; + pe__bundle_port_t *port = NULL; + GString *buffer = NULL; + int rc = pcmk_rc_ok; + pe__bundle_variant_data_t *bundle_data = NULL; + + get_bundle_variant_data(bundle_data, rsc); + + rc = pe__unpack_resource(clone_xml, &bundle_data->child, rsc, + rsc->priv->scheduler); + if (rc != pcmk_rc_ok) { + return rc; + } + + /* Currently, we always map the default authentication key location into the + * same location inside the container. + * + * Ideally, we would respect the host's PCMK_authkey_location, but: + * - it may be different on different nodes; + * - the actual connection will do extra checking to make sure the key file + * exists and is readable, that we can't do here on the DC + * - tools such as crm_resource and crm_simulate may not have the same + * environment variables as the cluster, causing operation digests to + * differ + * + * Always using the default location inside the container is fine, because + * we control the pacemaker_remote environment, and it avoids having to pass + * another environment variable to the container. + * + * @TODO A better solution may be to have only pacemaker_remote use the + * environment variable, and have the cluster nodes use a new cluster option + * for key location. This would introduce the limitation of the location + * being the same on all cluster nodes, but that's reasonable. + */ + mount_add(bundle_data, DEFAULT_REMOTE_KEY_LOCATION, + DEFAULT_REMOTE_KEY_LOCATION, NULL, pe__bundle_mount_none); + + if (!have_log_mount) { + mount_add(bundle_data, CRM_BUNDLE_DIR, "/var/log", NULL, + pe__bundle_mount_subdir); + } + + port = pcmk__assert_alloc(1, sizeof(pe__bundle_port_t)); + + if (bundle_data->control_port != NULL) { + port->source = pcmk__str_copy(bundle_data->control_port); + + } else { + /* If we wanted to respect PCMK_remote_port, we could use + * crm_default_remote_port() here and elsewhere in this file instead of + * DEFAULT_REMOTE_PORT. * - * @TODO A better solution may be to have only pacemaker_remote use the - * environment variable, and have the cluster nodes use a new - * cluster option for key location. This would introduce the limitation - * of the location being the same on all cluster nodes, but that's - * reasonable. + * However, it gains nothing, since we control both the container + * environment and the connection resource parameters, and the user can + * use a different port if desired by setting PCMK_XA_CONTROL_PORT. */ - mount_add(bundle_data, DEFAULT_REMOTE_KEY_LOCATION, - DEFAULT_REMOTE_KEY_LOCATION, NULL, pe__bundle_mount_none); + port->source = pcmk__itoa(DEFAULT_REMOTE_PORT); + } - if (need_log_mount) { - mount_add(bundle_data, CRM_BUNDLE_DIR, "/var/log", NULL, - pe__bundle_mount_subdir); - } + port->target = pcmk__str_copy(port->source); + bundle_data->ports = g_list_append(bundle_data->ports, port); + buffer = g_string_sized_new(1024); - port = pcmk__assert_alloc(1, sizeof(pe__bundle_port_t)); - if(bundle_data->control_port) { - port->source = strdup(bundle_data->control_port); - } else { - /* If we wanted to respect PCMK_remote_port, we could use - * crm_default_remote_port() here and elsewhere in this file instead - * of DEFAULT_REMOTE_PORT. - * - * However, it gains nothing, since we control both the container - * environment and the connection resource parameters, and the user - * can use a different port if desired by setting - * PCMK_XA_CONTROL_PORT. - */ - port->source = pcmk__itoa(DEFAULT_REMOTE_PORT); + for (GList *iter = bundle_data->child->priv->children; iter != NULL; + iter = iter->next) { + + pcmk__bundle_replica_t *replica = + pcmk__assert_alloc(1, sizeof(pcmk__bundle_replica_t)); + + replica->child = iter->data; + pcmk__set_rsc_flags(replica->child, pcmk__rsc_exclusive_probes); + replica->offset = offset++; + + /* Ensure the child's notify gets set based on the underlying + * primitive's value + */ + if (pcmk__is_set(replica->child->flags, pcmk__rsc_notify)) { + pcmk__set_rsc_flags(bundle_data->child, pcmk__rsc_notify); } - port->target = strdup(port->source); - bundle_data->ports = g_list_append(bundle_data->ports, port); - buffer = g_string_sized_new(1024); - for (childIter = bundle_data->child->priv->children; - childIter != NULL; childIter = childIter->next) { + allocate_ip(rsc, replica, buffer); + bundle_data->replicas = g_list_append(bundle_data->replicas, replica); - pcmk__bundle_replica_t *replica = NULL; + // coverity[null_field : FALSE] replica->child can't be NULL here + bundle_data->attribute_target = + g_hash_table_lookup(replica->child->priv->meta, + PCMK_META_CONTAINER_ATTRIBUTE_TARGET); + } - replica = pcmk__assert_alloc(1, sizeof(pcmk__bundle_replica_t)); - replica->child = childIter->data; - pcmk__set_rsc_flags(replica->child, pcmk__rsc_exclusive_probes); - replica->offset = lpc++; + bundle_data->container_host_options = g_string_free(buffer, false); - // Ensure the child's notify gets set based on the underlying primitive's value - if (pcmk__is_set(replica->child->flags, pcmk__rsc_notify)) { - pcmk__set_rsc_flags(bundle_data->child, pcmk__rsc_notify); - } + if (bundle_data->attribute_target != NULL) { + pcmk__insert_dup(rsc->priv->meta, PCMK_META_CONTAINER_ATTRIBUTE_TARGET, + bundle_data->attribute_target); + pcmk__insert_dup(bundle_data->child->priv->meta, + PCMK_META_CONTAINER_ATTRIBUTE_TARGET, + bundle_data->attribute_target); + } - allocate_ip(bundle_data, replica, buffer); - bundle_data->replicas = g_list_append(bundle_data->replicas, - replica); - // coverity[null_field] replica->child can't be NULL here - bundle_data->attribute_target = - g_hash_table_lookup(replica->child->priv->meta, - PCMK_META_CONTAINER_ATTRIBUTE_TARGET); - } - bundle_data->container_host_options = g_string_free(buffer, FALSE); - - if (bundle_data->attribute_target) { - pcmk__insert_dup(rsc->priv->meta, - PCMK_META_CONTAINER_ATTRIBUTE_TARGET, - bundle_data->attribute_target); - pcmk__insert_dup(bundle_data->child->priv->meta, - PCMK_META_CONTAINER_ATTRIBUTE_TARGET, - bundle_data->attribute_target); - } + return pcmk_rc_ok; +} - } else { - // Just a naked container, no pacemaker-remote - GString *buffer = g_string_sized_new(1024); +static void +create_simple_replicas(pcmk_resource_t *rsc) +{ + // Just a naked container, no pacemaker-remote + GString *buffer = g_string_sized_new(1024); + pe__bundle_variant_data_t *bundle_data = NULL; - for (int lpc = 0; lpc < bundle_data->nreplicas; lpc++) { - pcmk__bundle_replica_t *replica = NULL; + get_bundle_variant_data(bundle_data, rsc); - replica = pcmk__assert_alloc(1, sizeof(pcmk__bundle_replica_t)); - replica->offset = lpc; - allocate_ip(bundle_data, replica, buffer); - bundle_data->replicas = g_list_append(bundle_data->replicas, - replica); - } - bundle_data->container_host_options = g_string_free(buffer, FALSE); + for (int i = 0; i < bundle_data->nreplicas; i++) { + pcmk__bundle_replica_t *replica = + pcmk__assert_alloc(1, sizeof(pcmk__bundle_replica_t)); + + replica->offset = i; + allocate_ip(rsc, replica, buffer); + bundle_data->replicas = g_list_append(bundle_data->replicas, replica); } - for (GList *gIter = bundle_data->replicas; gIter != NULL; - gIter = gIter->next) { - pcmk__bundle_replica_t *replica = gIter->data; + bundle_data->container_host_options = g_string_free(buffer, false); +} - if (create_replica_resources(rsc, bundle_data, replica) != pcmk_rc_ok) { - pcmk__config_err("Failed unpacking resource %s", rsc->id); - pcmk__free_resource(rsc); - return FALSE; +bool +pe__unpack_bundle(pcmk_resource_t *rsc) +{ + xmlNode *clone_xml = NULL; + pe__bundle_variant_data_t *bundle_data = NULL; + bool have_log_mount = false; + + pcmk__assert(rsc != NULL); + pcmk__rsc_trace(rsc, "Processing resource %s...", rsc->id); + + bundle_data = pcmk__assert_alloc(1, sizeof(pe__bundle_variant_data_t)); + rsc->priv->variant_opaque = bundle_data; + + if (unpack_bundle_container(rsc) != pcmk_rc_ok) { + return false; + } + + unpack_bundle_network(rsc); + + have_log_mount = unpack_bundle_storage(rsc); + + if (unpack_bundle_primitive(rsc, &clone_xml) != pcmk_rc_ok) { + return false; + } + + if (clone_xml != NULL) { + int rc = create_child_resource(rsc, clone_xml, have_log_mount); + + pcmk__xml_free(clone_xml); + if (rc != pcmk_rc_ok) { + return false; } - /* Utilization needs special handling for bundles. It makes no sense for - * the inner primitive to have utilization, because it is tied - * one-to-one to the guest node created by the container resource -- and - * there's no way to set capacities for that guest node anyway. - * - * What the user really wants is to configure utilization for the - * container. However, the schema only allows utilization for - * primitives, and the container resource is implicit anyway, so the - * user can *only* configure utilization for the inner primitive. If - * they do, move the primitive's utilization values to the container. - * - * @TODO This means that bundles without an inner primitive can't have - * utilization. An alternative might be to allow utilization values in - * the top-level bundle XML in the schema, and copy those to each - * container. - */ - if (replica->child != NULL) { - GHashTable *empty = replica->container->priv->utilization; + } else { + create_simple_replicas(rsc); + } - replica->container->priv->utilization = - replica->child->priv->utilization; + for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { + pcmk__bundle_replica_t *replica = iter->data; - replica->child->priv->utilization = empty; + if (create_replica_resources(rsc, replica) != pcmk_rc_ok) { + pcmk__config_err("Failed unpacking resource %s", rsc->id); + return false; } } - if (bundle_data->child) { + if (bundle_data->child != NULL) { rsc->priv->children = g_list_append(rsc->priv->children, bundle_data->child); } - return TRUE; + + return true; } static int @@ -1381,9 +1519,8 @@ pe__find_bundle_replica(const pcmk_resource_t *bundle, const pcmk_node_t *node) pcmk__assert((bundle != NULL) && (node != NULL)); get_bundle_variant_data(bundle_data, bundle); - for (GList *gIter = bundle_data->replicas; gIter != NULL; - gIter = gIter->next) { - pcmk__bundle_replica_t *replica = gIter->data; + for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { + pcmk__bundle_replica_t *replica = iter->data; pcmk__assert((replica != NULL) && (replica->node != NULL)); if (pcmk__same_node(replica->node, node)) { @@ -1419,9 +1556,8 @@ pe__bundle_xml(pcmk__output_t *out, va_list args) print_everything = pcmk__str_in_list(rsc->id, only_rsc, pcmk__str_star_matches); - for (GList *gIter = bundle_data->replicas; gIter != NULL; - gIter = gIter->next) { - pcmk__bundle_replica_t *replica = gIter->data; + for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { + pcmk__bundle_replica_t *replica = iter->data; pcmk_resource_t *ip = replica->ip; pcmk_resource_t *child = replica->child; pcmk_resource_t *container = replica->container; @@ -1586,9 +1722,8 @@ pe__bundle_html(pcmk__output_t *out, va_list args) print_everything = pcmk__str_in_list(rsc->id, only_rsc, pcmk__str_star_matches); - for (GList *gIter = bundle_data->replicas; gIter != NULL; - gIter = gIter->next) { - pcmk__bundle_replica_t *replica = gIter->data; + for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { + pcmk__bundle_replica_t *replica = iter->data; pcmk_resource_t *ip = replica->ip; pcmk_resource_t *child = replica->child; pcmk_resource_t *container = replica->container; @@ -1737,9 +1872,8 @@ pe__bundle_text(pcmk__output_t *out, va_list args) print_everything = pcmk__str_in_list(rsc->id, only_rsc, pcmk__str_star_matches); - for (GList *gIter = bundle_data->replicas; gIter != NULL; - gIter = gIter->next) { - pcmk__bundle_replica_t *replica = gIter->data; + for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { + pcmk__bundle_replica_t *replica = iter->data; pcmk_resource_t *ip = replica->ip; pcmk_resource_t *child = replica->child; pcmk_resource_t *container = replica->container; @@ -1863,7 +1997,6 @@ pe__free_bundle(pcmk_resource_t *rsc) get_bundle_variant_data(bundle_data, rsc); pcmk__rsc_trace(rsc, "Freeing %s", rsc->id); - free(bundle_data->prefix); free(bundle_data->image); free(bundle_data->control_port); free(bundle_data->host_network); diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c index 47c7ff18917..3d68fbc043f 100644 --- a/lib/pengine/clone.c +++ b/lib/pengine/clone.c @@ -445,10 +445,8 @@ clone_unpack(pcmk_resource_t *rsc) bool clone_active(const pcmk_resource_t *rsc, bool all) { - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; bool child_active = child_rsc->priv->fns->active(child_rsc, all); if (all == FALSE && child_active) { @@ -510,10 +508,8 @@ is_set_recursive(const pcmk_resource_t *rsc, long long flag, bool any) return FALSE; } - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - if(is_set_recursive(gIter->data, flag, any)) { + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + if (is_set_recursive(iter->data, flag, any)) { if(any) { return TRUE; } @@ -556,10 +552,8 @@ pe__clone_xml(pcmk__output_t *out, va_list args) all = g_list_prepend(all, (gpointer) "*"); - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; if (pcmk__rsc_filtered_by_node(child_rsc, only_node)) { continue; @@ -630,7 +624,6 @@ pe__clone_default(pcmk__output_t *out, va_list args) GList *promoted_list = NULL; GList *started_list = NULL; - GList *gIter = NULL; const char *desc = NULL; @@ -653,9 +646,9 @@ pe__clone_default(pcmk__output_t *out, va_list args) && pcmk__str_in_list(rsc->id, only_rsc, pcmk__str_star_matches)); - for (gIter = rsc->priv->children; gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { gboolean print_full = FALSE; - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + pcmk_resource_t *child_rsc = iter->data; bool partially_active = child_rsc->priv->fns->active(child_rsc, false); if (pcmk__rsc_filtered_by_node(child_rsc, only_node)) { @@ -762,8 +755,8 @@ pe__clone_default(pcmk__output_t *out, va_list args) /* Promoted */ promoted_list = g_list_sort(promoted_list, pe__cmp_node_name); - for (gIter = promoted_list; gIter; gIter = gIter->next) { - pcmk_node_t *host = gIter->data; + for (GList *iter = promoted_list; iter != NULL; iter = iter->next) { + pcmk_node_t *host = iter->data; if (!pcmk__str_in_list(host->priv->name, only_node, pcmk__str_star_matches|pcmk__str_casei)) { @@ -785,8 +778,8 @@ pe__clone_default(pcmk__output_t *out, va_list args) /* Started/Unpromoted */ started_list = g_list_sort(started_list, pe__cmp_node_name); - for (gIter = started_list; gIter; gIter = gIter->next) { - pcmk_node_t *host = gIter->data; + for (GList *iter = started_list; iter != NULL; iter = iter->next) { + pcmk_node_t *host = iter->data; if (!pcmk__str_in_list(host->priv->name, only_node, pcmk__str_star_matches|pcmk__str_casei)) { @@ -949,10 +942,8 @@ clone_resource_state(const pcmk_resource_t *rsc, bool current) { enum rsc_role_e clone_role = pcmk_role_unknown; - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; enum rsc_role_e a_role = child_rsc->priv->fns->state(child_rsc, current); diff --git a/lib/pengine/group.c b/lib/pengine/group.c index bb6cb62c2d2..5cfaf238396 100644 --- a/lib/pengine/group.c +++ b/lib/pengine/group.c @@ -99,10 +99,8 @@ inactive_resources(pcmk_resource_t *rsc) { int retval = 0; - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; if (!child_rsc->priv->fns->active(child_rsc, true)) { retval++; @@ -239,10 +237,8 @@ group_active(const pcmk_resource_t *rsc, bool all) gboolean c_all = TRUE; gboolean c_any = FALSE; - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; if (child_rsc->priv->fns->active(child_rsc, all)) { c_any = TRUE; @@ -285,17 +281,15 @@ pe__group_xml(pcmk__output_t *out, va_list args) return rc; } - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; if (skip_child_rsc(rsc, child_rsc, parent_passes, only_rsc, show_opts)) { continue; } if (rc == pcmk_rc_no_output) { - char *count = pcmk__itoa(g_list_length(gIter)); + char *count = pcmk__itoa(g_list_length(iter)); const char *maintenance = pcmk__flag_text(rsc->flags, pcmk__rsc_maintenance); const char *managed = pcmk__flag_text(rsc->flags, @@ -369,9 +363,10 @@ pe__group_default(pcmk__output_t *out, va_list args) } } else { - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; + iter = iter->next) { + + pcmk_resource_t *child_rsc = iter->data; if (skip_child_rsc(rsc, child_rsc, parent_passes, only_rsc, show_opts)) { continue; @@ -406,10 +401,8 @@ group_resource_state(const pcmk_resource_t *rsc, bool current) { enum rsc_role_e group_role = pcmk_role_unknown; - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; enum rsc_role_e role = child_rsc->priv->fns->state(child_rsc, current); diff --git a/lib/pengine/native.c b/lib/pengine/native.c index acf6b839f09..27a010d3476 100644 --- a/lib/pengine/native.c +++ b/lib/pengine/native.c @@ -66,10 +66,10 @@ native_priority_to_node(pcmk_resource_t *rsc, pcmk_node_t *node, const pcmk_resource_t *launcher = NULL; launcher = node->priv->remote->priv->launcher; - for (GList *gIter = launcher->priv->active_nodes; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = launcher->priv->active_nodes; iter != NULL; + iter = iter->next) { - pcmk_node_t *a_node = gIter->data; + pcmk_node_t *a_node = iter->data; a_node->priv->priority += priority; pcmk__rsc_trace(rsc, @@ -91,10 +91,10 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, CRM_CHECK(node != NULL, return); - for (GList *gIter = rsc->priv->active_nodes; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->active_nodes; iter != NULL; + iter = iter->next) { - pcmk_node_t *a_node = (pcmk_node_t *) gIter->data; + pcmk_node_t *a_node = iter->data; if (pcmk__same_node(a_node, node)) { return; @@ -137,7 +137,7 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, switch (rsc->priv->multiply_active_policy) { case pcmk__multiply_active_stop: { - GHashTableIter gIter; + GHashTableIter iter; pcmk_node_t *local_node = NULL; /* make sure it doesn't come up again */ @@ -145,8 +145,11 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, g_hash_table_destroy); rsc->priv->allowed_nodes = pe__node_list2table(scheduler->nodes); - g_hash_table_iter_init(&gIter, rsc->priv->allowed_nodes); - while (g_hash_table_iter_next(&gIter, NULL, (void **)&local_node)) { + g_hash_table_iter_init(&iter, rsc->priv->allowed_nodes); + + while (g_hash_table_iter_next(&iter, NULL, + (void **) &local_node)) { + local_node->assign->score = -PCMK_SCORE_INFINITY; } } @@ -163,9 +166,10 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, && (parent->priv->multiply_active_policy == pcmk__multiply_active_block)) { - for (GList *gIter = parent->priv->children; - gIter != NULL; gIter = gIter->next) { - pcmk_resource_t *child = gIter->data; + for (GList *iter = parent->priv->children; iter != NULL; + iter = iter->next) { + + pcmk_resource_t *child = iter->data; pcmk__clear_rsc_flags(child, pcmk__rsc_managed); pcmk__set_rsc_flags(child, pcmk__rsc_blocked); @@ -311,10 +315,8 @@ native_find_rsc(pcmk_resource_t *rsc, const char *id, return rsc; } - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child = iter->data; result = rsc->priv->fns->find_rsc(child, id, on_node, flags); if (result) { @@ -327,10 +329,10 @@ native_find_rsc(pcmk_resource_t *rsc, const char *id, bool native_active(const pcmk_resource_t *rsc, bool all) { - for (GList *gIter = rsc->priv->active_nodes; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->active_nodes; iter != NULL; + iter = iter->next) { - pcmk_node_t *a_node = (pcmk_node_t *) gIter->data; + pcmk_node_t *a_node = iter->data; if (a_node->details->unclean) { pcmk__rsc_trace(rsc, "Resource %s: %s is unclean", @@ -804,10 +806,10 @@ pe__resource_xml(pcmk__output_t *out, va_list args) pcmk__assert(rc == pcmk_rc_ok); - for (GList *gIter = rsc->priv->active_nodes; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->active_nodes; iter != NULL; + iter = iter->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter->data; + pcmk_node_t *node = iter->data; const char *cached = pcmk__btoa(node->details->online); rc = pe__name_and_nvpairs_xml(out, false, PCMK_XE_NODE, @@ -910,10 +912,10 @@ native_location(const pcmk_resource_t *rsc, GList **list, uint32_t target) if (rsc->priv->children != NULL) { - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->children; iter != NULL; + iter = iter->next) { - pcmk_resource_t *child = (pcmk_resource_t *) gIter->data; + pcmk_resource_t *child = iter->data; child->priv->fns->location(child, &result, target); } @@ -938,10 +940,8 @@ native_location(const pcmk_resource_t *rsc, GList **list, uint32_t target) } if (list) { - GList *gIter = result; - - for (; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter->data; + for (GList *iter = result; iter != NULL; iter = iter->next) { + pcmk_node_t *node = iter->data; if ((*list == NULL) || (pe_find_node_id(*list, node->priv->id) == NULL)) { @@ -957,10 +957,8 @@ native_location(const pcmk_resource_t *rsc, GList **list, uint32_t target) static void get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_table) { - GList *gIter = rsc_list; - - for (; gIter != NULL; gIter = gIter->next) { - pcmk_resource_t *rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc_list; iter != NULL; iter = iter->next) { + pcmk_resource_t *rsc = iter->data; const char *class = pcmk__xe_get(rsc->priv->xml, PCMK_XA_CLASS); const char *kind = pcmk__xe_get(rsc->priv->xml, PCMK_XA_TYPE); @@ -998,10 +996,10 @@ get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_tabl } if (active_table) { - for (GList *gIter2 = rsc->priv->active_nodes; - gIter2 != NULL; gIter2 = gIter2->next) { + for (GList *iter2 = rsc->priv->active_nodes; iter2 != NULL; + iter2 = iter2->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter2->data; + pcmk_node_t *node = iter2->data; GHashTable *node_table = NULL; if (!node->details->unclean && !node->details->online @@ -1055,8 +1053,8 @@ pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, uint32_t show_opts) sorted_rscs = g_hash_table_get_keys(rsc_table); sorted_rscs = g_list_sort(sorted_rscs, (GCompareFunc) strcmp); - for (GList *gIter = sorted_rscs; gIter; gIter = gIter->next) { - char *type = (char *) gIter->data; + for (GList *iter = sorted_rscs; iter != NULL; iter = iter->next) { + char *type = iter->data; int *rsc_counter = g_hash_table_lookup(rsc_table, type); GList *sorted_nodes = NULL; @@ -1069,8 +1067,8 @@ pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, uint32_t show_opts) sorted_nodes = g_hash_table_get_keys(active_table); sorted_nodes = g_list_sort(sorted_nodes, (GCompareFunc) pcmk__numeric_strcasecmp); - for (GList *gIter2 = sorted_nodes; gIter2; gIter2 = gIter2->next) { - char *node_name = (char *) gIter2->data; + for (GList *iter2 = sorted_nodes; iter2 != NULL; iter2 = iter2->next) { + char *node_name = iter2->data; GHashTable *node_table = g_hash_table_lookup(active_table, node_name); int *active_counter = NULL; diff --git a/lib/pengine/pe_actions.c b/lib/pengine/pe_actions.c index d71c800cf04..3ebbe79d06a 100644 --- a/lib/pengine/pe_actions.c +++ b/lib/pengine/pe_actions.c @@ -1141,8 +1141,8 @@ get_pseudo_op(const char *name, pcmk_scheduler_t *scheduler) static GList * find_unfencing_devices(GList *candidates, GList *matches) { - for (GList *gIter = candidates; gIter != NULL; gIter = gIter->next) { - pcmk_resource_t *candidate = gIter->data; + for (GList *iter = candidates; iter != NULL; iter = iter->next) { + pcmk_resource_t *candidate = iter->data; if (candidate->priv->children != NULL) { matches = find_unfencing_devices(candidate->priv->children, @@ -1171,7 +1171,6 @@ node_priority_fencing_delay(const pcmk_node_t *node, int online_count = 0; int top_priority = 0; int lowest_priority = 0; - GList *gIter = NULL; // PCMK_OPT_PRIORITY_FENCING_DELAY is disabled if (scheduler->priv->priority_fencing_ms == 0U) { @@ -1189,8 +1188,8 @@ node_priority_fencing_delay(const pcmk_node_t *node, return 0; } - for (gIter = scheduler->nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *n = gIter->data; + for (GList *iter = scheduler->nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *n = iter->data; if (n->priv->variant != pcmk__node_variant_cluster) { continue; @@ -1264,8 +1263,8 @@ pe_fence_op(pcmk_node_t *node, const char *op, bool optional, GList *matches = find_unfencing_devices(scheduler->priv->resources, NULL); - for (GList *gIter = matches; gIter != NULL; gIter = gIter->next) { - pcmk_resource_t *match = gIter->data; + for (GList *iter = matches; iter != NULL; iter = iter->next) { + pcmk_resource_t *match = iter->data; const char *agent = g_hash_table_lookup(match->priv->meta, PCMK_XA_TYPE); pcmk__op_digest_t *data = NULL; @@ -1387,8 +1386,8 @@ find_first_action(const GList *input, const char *uuid, const char *task, { CRM_CHECK(uuid || task, return NULL); - for (const GList *gIter = input; gIter != NULL; gIter = gIter->next) { - pcmk_action_t *action = (pcmk_action_t *) gIter->data; + for (const GList *iter = input; iter != NULL; iter = iter->next) { + pcmk_action_t *action = iter->data; if (uuid != NULL && !pcmk__str_eq(uuid, action->uuid, pcmk__str_casei)) { continue; @@ -1413,13 +1412,12 @@ find_first_action(const GList *input, const char *uuid, const char *task, GList * find_actions(GList *input, const char *key, const pcmk_node_t *on_node) { - GList *gIter = input; GList *result = NULL; CRM_CHECK(key != NULL, return NULL); - for (; gIter != NULL; gIter = gIter->next) { - pcmk_action_t *action = (pcmk_action_t *) gIter->data; + for (GList *iter = input; iter != NULL; iter = iter->next) { + pcmk_action_t *action = iter->data; if (!pcmk__str_eq(key, action->uuid, pcmk__str_casei)) { continue; @@ -1456,8 +1454,8 @@ find_actions_exact(GList *input, const char *key, const pcmk_node_t *on_node) return NULL; } - for (GList *gIter = input; gIter != NULL; gIter = gIter->next) { - pcmk_action_t *action = (pcmk_action_t *) gIter->data; + for (GList *iter = input; iter != NULL; iter = iter->next) { + pcmk_action_t *action = iter->data; if ((action->node != NULL) && pcmk__str_eq(key, action->uuid, pcmk__str_casei) diff --git a/lib/pengine/pe_notif.c b/lib/pengine/pe_notif.c index 4b200a5bb00..ccef06234bc 100644 --- a/lib/pengine/pe_notif.c +++ b/lib/pengine/pe_notif.c @@ -201,8 +201,8 @@ notify_entries_to_strings(GList *list, GString **rsc_names, // Sort input list for user-friendliness (and ease of filtering duplicates) list = g_list_sort(list, compare_notify_entries); - for (GList *gIter = list; gIter != NULL; gIter = gIter->next) { - notify_entry_t *entry = (notify_entry_t *) gIter->data; + for (GList *iter = list; iter != NULL; iter = iter->next) { + notify_entry_t *entry = iter->data; // Entry must have a resource (with ID) CRM_LOG_ASSERT((entry != NULL) && (entry->rsc != NULL) diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c index 7b43314937e..8fb85021b71 100644 --- a/lib/pengine/pe_output.c +++ b/lib/pengine/pe_output.c @@ -68,10 +68,8 @@ add_extra_info(const pcmk_node_t *node, GList *rsc_list, pcmk_scheduler_t *scheduler, const char *attrname, int *expected_score) { - GList *gIter = NULL; - - for (gIter = rsc_list; gIter != NULL; gIter = gIter->next) { - pcmk_resource_t *rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc_list; iter != NULL; iter = iter->next) { + pcmk_resource_t *rsc = iter->data; const char *type = g_hash_table_lookup(rsc->priv->meta, PCMK_XA_TYPE); const char *name = NULL; @@ -379,9 +377,11 @@ static bool is_mixed_version(pcmk_scheduler_t *scheduler) { const char *feature_set = NULL; - for (GList *gIter = scheduler->nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node = gIter->data; + + for (GList *iter = scheduler->nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *node = iter->data; const char *node_feature_set = get_node_feature_set(node); + if (node_feature_set != NULL) { if (feature_set == NULL) { feature_set = node_feature_set; @@ -730,13 +730,13 @@ ban_list(pcmk__output_t *out, va_list args) { uint32_t show_opts = va_arg(args, uint32_t); bool print_spacer = va_arg(args, int); - GList *gIter, *gIter2; int rc = pcmk_rc_no_output; /* Print each ban */ - for (gIter = scheduler->priv->location_constraints; - gIter != NULL; gIter = gIter->next) { - pcmk__location_t *location = gIter->data; + for (GList *iter = scheduler->priv->location_constraints; iter != NULL; + iter = iter->next) { + + pcmk__location_t *location = iter->data; const pcmk_resource_t *rsc = location->rsc; if (prefix != NULL && !g_str_has_prefix(location->id, prefix)) { @@ -750,8 +750,10 @@ ban_list(pcmk__output_t *out, va_list args) { continue; } - for (gIter2 = location->nodes; gIter2 != NULL; gIter2 = gIter2->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter2->data; + for (GList *iter2 = location->nodes; iter2 != NULL; + iter2 = iter2->next) { + + pcmk_node_t *node = iter2->data; if (node->assign->score < 0) { PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Negative Location Constraints"); @@ -1979,13 +1981,13 @@ node_text(pcmk__output_t *out, va_list args) { } } else { - GList *gIter2 = NULL; - out->begin_list(out, NULL, NULL, "%s", str->str); out->begin_list(out, NULL, NULL, "Resources"); - for (gIter2 = node->details->running_rsc; gIter2 != NULL; gIter2 = gIter2->next) { - pcmk_resource_t *rsc = (pcmk_resource_t *) gIter2->data; + for (GList *iter2 = node->details->running_rsc; iter2 != NULL; + iter2 = iter2->next) { + + pcmk_resource_t *rsc = iter2->data; show_opts |= pcmk_show_rsc_only; out->message(out, (const char *) rsc->priv->xml->name, @@ -2364,8 +2366,8 @@ node_attribute_list(pcmk__output_t *out, va_list args) { int rc = pcmk_rc_no_output; /* Display each node's attributes */ - for (GList *gIter = scheduler->nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node = gIter->data; + for (GList *iter = scheduler->nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *node = iter->data; GList *attr_list = NULL; GHashTableIter iter; @@ -2566,8 +2568,8 @@ node_list_html(pcmk__output_t *out, va_list args) { int rc = pcmk_rc_no_output; - for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter->data; + for (GList *iter = nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *node = iter->data; if (!pcmk__str_in_list(node->priv->name, only_node, pcmk__str_star_matches|pcmk__str_casei)) { @@ -2601,8 +2603,8 @@ node_list_text(pcmk__output_t *out, va_list args) { int rc = pcmk_rc_no_output; - for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter->data; + for (GList *iter = nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *node = iter->data; char *node_name = pe__node_display_name(node, pcmk__is_set(show_opts, pcmk_show_node_id)); @@ -2705,8 +2707,8 @@ node_list_xml(pcmk__output_t *out, va_list args) { * value of the list's PCMK_XA_NAME attribute. */ out->begin_list(out, NULL, NULL, PCMK_XE_NODES); - for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node = (pcmk_node_t *) gIter->data; + for (GList *iter = nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *node = iter->data; if (!pcmk__str_in_list(node->priv->name, only_node, pcmk__str_star_matches|pcmk__str_casei)) { @@ -3172,12 +3174,11 @@ resource_operation_list(pcmk__output_t *out, va_list args) GList *op_list = va_arg(args, GList *); uint32_t show_opts = va_arg(args, uint32_t); - GList *gIter = NULL; int rc = pcmk_rc_no_output; /* Print each operation */ - for (gIter = op_list; gIter != NULL; gIter = gIter->next) { - xmlNode *xml_op = (xmlNode *) gIter->data; + for (GList *iter = op_list; iter != NULL; iter = iter->next) { + xmlNode *xml_op = iter->data; const char *task = pcmk__xe_get(xml_op, PCMK_XA_OPERATION); const char *interval_ms_s = pcmk__xe_get(xml_op, PCMK_META_INTERVAL); const char *op_rc = pcmk__xe_get(xml_op, PCMK__XA_RC_CODE); diff --git a/lib/pengine/remote.c b/lib/pengine/remote.c index 45a15f7ee07..6e123c203ca 100644 --- a/lib/pengine/remote.c +++ b/lib/pengine/remote.c @@ -1,5 +1,5 @@ /* - * Copyright 2013-2025 the Pacemaker project contributors + * Copyright 2013-2026 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -34,10 +34,10 @@ pe__resource_contains_guest_node(const pcmk_scheduler_t *scheduler, if ((rsc != NULL) && (scheduler != NULL) && pcmk__is_set(scheduler->flags, pcmk__sched_have_remote_nodes)) { - for (GList *gIter = rsc->priv->launched; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->launched; iter != NULL; + iter = iter->next) { - pcmk_resource_t *launched = gIter->data; + pcmk_resource_t *launched = iter->data; if (pcmk__is_set(launched->flags, pcmk__rsc_is_remote_connection)) { return launched; diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c index 1430a58a146..14c321a3b2b 100644 --- a/lib/pengine/unpack.c +++ b/lib/pengine/unpack.c @@ -831,7 +831,6 @@ gboolean unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler) { xmlNode *xml_obj = NULL; - GList *gIter = NULL; scheduler->priv->templates = pcmk__strkey_table(free, pcmk__free_idref); @@ -871,10 +870,10 @@ unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler) pcmk__rsc_trace(new_rsc, "Added resource %s", new_rsc->id); } - for (gIter = scheduler->priv->resources; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = scheduler->priv->resources; iter != NULL; + iter = iter->next) { - pcmk_resource_t *rsc = (pcmk_resource_t *) gIter->data; + pcmk_resource_t *rsc = iter->data; unpack_launcher(rsc, scheduler); link_rsc2remotenode(scheduler, rsc); @@ -1472,8 +1471,8 @@ unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler) * we can stop connections for node shutdowns, and check the online status * of remote/guest nodes that didn't have any node history to unpack. */ - for (GList *gIter = scheduler->nodes; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *this_node = gIter->data; + for (GList *iter = scheduler->nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *this_node = iter->data; if (!pcmk__is_pacemaker_remote_node(this_node)) { continue; @@ -2595,10 +2594,9 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, } else { GList *possible_matches = pe__resource_actions(rsc, node, PCMK_ACTION_STOP, FALSE); - GList *gIter = possible_matches; - for (; gIter != NULL; gIter = gIter->next) { - pcmk_action_t *stop = (pcmk_action_t *) gIter->data; + for (GList *iter = possible_matches; iter != NULL; iter = iter->next) { + pcmk_action_t *stop = iter->data; pcmk__set_action_flags(stop, pcmk__action_optional); } @@ -2627,14 +2625,13 @@ process_recurring(pcmk_node_t *node, pcmk_resource_t *rsc, int counter = -1; const char *task = NULL; const char *status = NULL; - GList *gIter = sorted_op_list; pcmk__assert(rsc != NULL); pcmk__rsc_trace(rsc, "%s: Start index %d, stop index = %d", rsc->id, start_index, stop_index); - for (; gIter != NULL; gIter = gIter->next) { - xmlNode *rsc_op = (xmlNode *) gIter->data; + for (GList *iter = sorted_op_list; iter != NULL; iter = iter->next) { + xmlNode *rsc_op = iter->data; guint interval_ms = 0; char *key = NULL; @@ -2774,7 +2771,6 @@ static pcmk_resource_t * unpack_lrm_resource(pcmk_node_t *node, const xmlNode *lrm_resource, pcmk_scheduler_t *scheduler) { - GList *gIter = NULL; int stop_index = -1; int start_index = -1; enum rsc_role_e req_role = pcmk_role_unknown; @@ -2839,8 +2835,8 @@ unpack_lrm_resource(pcmk_node_t *node, const xmlNode *lrm_resource, rsc->priv->orig_role = pcmk_role_unknown; sorted_op_list = g_list_sort(op_list, sort_op_by_callid); - for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) { - xmlNode *rsc_op = (xmlNode *) gIter->data; + for (GList *iter = sorted_op_list; iter != NULL; iter = iter->next) { + xmlNode *rsc_op = iter->data; unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail); } @@ -5037,7 +5033,6 @@ extract_operations(const char *node, const char *rsc, xmlNode * rsc_entry, gbool xmlNode *rsc_op = NULL; - GList *gIter = NULL; GList *op_list = NULL; GList *sorted_op_list = NULL; @@ -5070,8 +5065,8 @@ extract_operations(const char *node, const char *rsc, xmlNode * rsc_entry, gbool calculate_active_ops(sorted_op_list, &start_index, &stop_index); - for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) { - xmlNode *rsc_op = (xmlNode *) gIter->data; + for (GList *iter = sorted_op_list; iter != NULL; iter = iter->next) { + xmlNode *rsc_op = iter->data; counter++; diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c index 7906fbe6305..9aa316d028b 100644 --- a/lib/pengine/utils.c +++ b/lib/pengine/utils.c @@ -153,10 +153,10 @@ pe__node_list2table(const GList *list) GHashTable *result = NULL; result = pcmk__strkey_table(NULL, pcmk__free_node_copy); - for (const GList *gIter = list; gIter != NULL; gIter = gIter->next) { + for (const GList *iter = list; iter != NULL; iter = iter->next) { pcmk_node_t *new_node = NULL; - new_node = pe__copy_node((const pcmk_node_t *) gIter->data); + new_node = pe__copy_node((const pcmk_node_t *) iter->data); g_hash_table_insert(result, (gpointer) new_node->priv->id, new_node); } return result; @@ -217,8 +217,8 @@ pe__output_node_weights(const pcmk_resource_t *rsc, const char *comment, GList *list = g_list_sort(g_hash_table_get_values(nodes), pe__cmp_node_name); - for (const GList *gIter = list; gIter != NULL; gIter = gIter->next) { - const pcmk_node_t *node = (const pcmk_node_t *) gIter->data; + for (const GList *iter = list; iter != NULL; iter = iter->next) { + const pcmk_node_t *node = iter->data; out->message(out, "node-weight", rsc, comment, node->priv->name, pcmk_readable_score(node->assign->score)); @@ -306,10 +306,8 @@ pe__show_node_scores_as(const char *file, const char *function, int line, } // If this resource has children, repeat recursively for each - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { - - pcmk_resource_t *child = (pcmk_resource_t *) gIter->data; + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child = iter->data; pe__show_node_scores_as(file, function, line, to_log, child, comment, child->priv->allowed_nodes, scheduler); @@ -370,10 +368,10 @@ resource_node_score(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, return; } else { - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->children; iter != NULL; + iter = iter->next) { - pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; + pcmk_resource_t *child_rsc = iter->data; resource_node_score(child_rsc, node, score, tag); } @@ -401,10 +399,8 @@ resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, resource_node_score(rsc, node, score, tag); } else if (scheduler != NULL) { - GList *gIter = scheduler->nodes; - - for (; gIter != NULL; gIter = gIter->next) { - pcmk_node_t *node_iter = (pcmk_node_t *) gIter->data; + for (GList *iter = scheduler->nodes; iter != NULL; iter = iter->next) { + pcmk_node_t *node_iter = iter->data; resource_node_score(rsc, node_iter, score, tag); } @@ -480,7 +476,6 @@ get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role) gboolean order_actions(pcmk_action_t *first, pcmk_action_t *then, uint32_t flags) { - GList *gIter = NULL; pcmk__related_action_t *wrapper = NULL; GList *list = NULL; @@ -499,9 +494,8 @@ order_actions(pcmk_action_t *first, pcmk_action_t *then, uint32_t flags) pcmk__assert(first != then); /* Filter dups, otherwise update_action_states() has too much work to do */ - gIter = first->actions_after; - for (; gIter != NULL; gIter = gIter->next) { - pcmk__related_action_t *after = gIter->data; + for (GList *iter = first->actions_after; iter != NULL; iter = iter->next) { + pcmk__related_action_t *after = iter->data; if ((after->action == then) && pcmk__any_flags_set(after->flags, flags)) { @@ -587,11 +581,10 @@ pe__clear_resource_flags_recursive(pcmk_resource_t *rsc, uint64_t flags) { pcmk__clear_rsc_flags(rsc, flags); - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; - pe__clear_resource_flags_recursive((pcmk_resource_t *) gIter->data, - flags); + pe__clear_resource_flags_recursive(child_rsc, flags); } } @@ -612,11 +605,10 @@ pe__set_resource_flags_recursive(pcmk_resource_t *rsc, uint64_t flags) { pcmk__set_rsc_flags(rsc, flags); - for (GList *gIter = rsc->priv->children; - gIter != NULL; gIter = gIter->next) { + for (GList *iter = rsc->priv->children; iter != NULL; iter = iter->next) { + pcmk_resource_t *child_rsc = iter->data; - pe__set_resource_flags_recursive((pcmk_resource_t *) gIter->data, - flags); + pe__set_resource_flags_recursive(child_rsc, flags); } } @@ -787,8 +779,8 @@ pe__filter_rsc_list(GList *rscs, GList *filter) { GList *retval = NULL; - for (GList *gIter = rscs; gIter; gIter = gIter->next) { - pcmk_resource_t *rsc = (pcmk_resource_t *) gIter->data; + for (GList *iter = rscs; iter != NULL; iter = iter->next) { + pcmk_resource_t *rsc = iter->data; /* I think the second condition is safe here for all callers of this * function. If not, it needs to move into pe__node_text. diff --git a/lib/services/services.c b/lib/services/services.c index e752fdac75f..b9b7c27735c 100644 --- a/lib/services/services.c +++ b/lib/services/services.c @@ -1340,44 +1340,6 @@ services__exit_reason(const svc_action_t *action) return action->opaque->exit_reason; } -/*! - * \internal - * \brief Steal stdout from an action - * - * \param[in,out] action Action whose stdout is desired - * - * \return Action's stdout (which may be NULL) - * \note Upon return, \p action will no longer track the output, so it is the - * caller's responsibility to free the return value. - */ -char * -services__grab_stdout(svc_action_t *action) -{ - char *output = action->stdout_data; - - action->stdout_data = NULL; - return output; -} - -/*! - * \internal - * \brief Steal stderr from an action - * - * \param[in,out] action Action whose stderr is desired - * - * \return Action's stderr (which may be NULL) - * \note Upon return, \p action will no longer track the output, so it is the - * caller's responsibility to free the return value. - */ -char * -services__grab_stderr(svc_action_t *action) -{ - char *output = action->stderr_data; - - action->stderr_data = NULL; - return output; -} - // Deprecated functions kept only for backward API compatibility // LCOV_EXCL_START diff --git a/python/pacemaker/_cts/patterns.py b/python/pacemaker/_cts/patterns.py index 4b69cfe9a14..963f460f739 100644 --- a/python/pacemaker/_cts/patterns.py +++ b/python/pacemaker/_cts/patterns.py @@ -239,7 +239,7 @@ def __init__(self): self._components["corosync-ignore"] = components_common_ignore + [ r"Could not connect to Corosync CFG: Internal corosync error", - r"error:.*Connection to the CPG API failed: Library error", + r"error:.*Connection to the CPG API failed: Internal corosync error", r"\[[0-9]+\] exited with status [0-9]+ \(", r"\[[0-9]+\] terminated with signal 15", r"pacemaker-based.*error:.*Corosync connection lost", diff --git a/tools/crm_resource.c b/tools/crm_resource.c index 8e655d1f6e3..991fb88c3c7 100644 --- a/tools/crm_resource.c +++ b/tools/crm_resource.c @@ -268,16 +268,24 @@ static void start_mainloop(pcmk_ipc_api_t *capi) { // @TODO See if we can avoid setting exit_code as a global variable - unsigned int count = pcmk_controld_api_replies_expected(capi); + unsigned int count = 0; + + if (capi == NULL) { + // Should happen only during a dry run due to CIB_file being set + return; + } - if (count > 0) { - out->info(out, "Waiting for %u %s from the controller", - count, pcmk__plural_alt(count, "reply", "replies")); - exit_code = CRM_EX_DISCONNECT; // For unexpected disconnects - mainloop = g_main_loop_new(NULL, FALSE); - pcmk__create_timer(MESSAGE_TIMEOUT_S * 1000, resource_ipc_timeout, NULL); - g_main_loop_run(mainloop); + count = pcmk_controld_api_replies_expected(capi); + if (count == 0) { + return; } + + out->info(out, "Waiting for %u %s from the controller", count, + pcmk__plural_alt(count, "reply", "replies")); + exit_code = CRM_EX_DISCONNECT; // For unexpected disconnects + mainloop = g_main_loop_new(NULL, false); + pcmk__create_timer((MESSAGE_TIMEOUT_S * 1000), resource_ipc_timeout, NULL); + g_main_loop_run(mainloop); } static GList *