Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
pacemaker
pacemaker-libservices-handle-in-flight-first-ca...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pacemaker-libservices-handle-in-flight-first-cancelling-an-operation.patch of Package pacemaker
commit dc36d4375c049024a6f9e4d2277a3e6444fad05b Author: Ken Gaillot <kgaillot@redhat.com> Date: Tue Feb 28 15:41:10 2017 -0600 Refactor: libservices: handle in-flight case first when cancelling an operation will make next bugfix easier diff --git a/lib/services/services.c b/lib/services/services.c index 78a078133..dba4e6675 100644 --- a/lib/services/services.c +++ b/lib/services/services.c @@ -470,43 +470,62 @@ cancel_recurring_action(svc_action_t * op) return TRUE; } +/*! + * \brief Cancel a recurring action + * + * \param[in] name Name of resource that operation is for + * \param[in] action Name of operation to cancel + * \param[in] interval Interval of operation to cancel + * + * \return TRUE if action was successfully cancelled, FALSE otherwise + */ gboolean services_action_cancel(const char *name, const char *action, int interval) { - svc_action_t *op = NULL; + gboolean cancelled = FALSE; char *id = generate_op_key(name, action, interval); + svc_action_t *op = g_hash_table_lookup(recurring_actions, id); - if (!(op = g_hash_table_lookup(recurring_actions, id))) { - free(id); - return FALSE; + /* We can only cancel a recurring action */ + if (op == NULL) { + goto done; } - /* Always kill the recurring timer */ + /* Tell operation_finalize() not to reschedule the operation */ + op->cancel = TRUE; + + /* Stop tracking it as a recurring operation, and stop its timer */ cancel_recurring_action(op); - if (op->pid == 0) { - op->status = PCMK_LRM_OP_CANCELLED; - if (op->opaque->callback) { - op->opaque->callback(op); + /* If the op has a PID, it's an in-flight child process, so kill it. + * + * Whether the kill succeeds or fails, the main loop will send the op to + * operation_finished() (and thus operation_finalize()) when the process + * goes away. + */ + if (op->pid != 0) { + crm_info("Terminating in-flight op %s (pid %d) early because it was cancelled", + id, op->pid); + cancelled = mainloop_child_kill(op->pid); + if (cancelled == FALSE) { + crm_err("Termination of %s (pid %d) failed", id, op->pid); } + goto done; + } - blocked_ops = g_list_remove(blocked_ops, op); - services_action_free(op); - - } else { - crm_info("Cancelling in-flight op: performing early termination of %s (pid=%d)", id, op->pid); - op->cancel = 1; - if (mainloop_child_kill(op->pid) == FALSE) { - /* even though the early termination failed, - * the op will be marked as cancelled once it completes. */ - crm_err("Termination of %s (pid=%d) failed", id, op->pid); - free(id); - return FALSE; - } + /* Otherwise, operation is not in-flight, just report as cancelled */ + op->status = PCMK_LRM_OP_CANCELLED; + if (op->opaque->callback) { + op->opaque->callback(op); } + blocked_ops = g_list_remove(blocked_ops, op); + services_action_free(op); + cancelled = TRUE; + +done: free(id); - return TRUE; + return cancelled; } gboolean
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor