-
Notifications
You must be signed in to change notification settings - Fork 352
Standardize IPC code in execd #4018
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+577
−379
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
d629ce3
Refactor: daemons: Split up IPC code in execd.
clumens 462e7ab
Refactor: daemons: Rename functions in execd_ipc.c.
clumens c83f351
Refactor: daemons: Standardize functions in execd_ipc.c.
clumens 7acc4f3
Refactor: daemons: Standardize handling IPC requests in execd.
clumens b436713
Refactor: libcrmcommon: Add pcmk__serve_execd_ipc.
clumens d4d378b
Refactor: daemons: Standardize execd IPC startup/shutdown.
clumens 7f48b4f
Refactor: daemons: Add some additional checks to execd_ipc_dispatch.
clumens 5f45273
Refactor: daemons: Standardize functions in remoted_proxy.c.
clumens 287c0fa
Refactor: daemons: Clean up header blocks in some of execd.
clumens 1dda700
Low: daemons: Clean up XML memory in IPC dispatch functions.
clumens bba01e1
Refactor: libcrmcommon: Standardize IPC startup failure messages.
clumens a23270f
Low: daemons: Set ipc_flags in lrmd_remote_client_msg to 0.
clumens 7f82ca1
Refactor: daemons: Remove check on client->id from execd_ipc_dispatch.
clumens 0c2b94b
Refactor: daemons: Don't call _unregister_handlers from _ipc_cleanup.
clumens 74852a8
Refactor: daemons: Use g_clear_pointer in IPC cleanup functions.
clumens 1eb3aca
Refactor: daemons: Use g_clear_pointer in ipc_proxy_cleanup.
clumens 69411f2
Low: daemons: Use crm_ipc_client_response in lrmd_remote_client_msg.
clumens File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,227 @@ | ||
| /* | ||
| * Copyright 2012-2026 the Pacemaker project contributors | ||
| * | ||
| * The version control history for this file may have further details. | ||
| * | ||
| * This source code is licensed under the GNU Lesser General Public License | ||
| * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. | ||
| */ | ||
|
|
||
| #include <crm_internal.h> | ||
|
|
||
| #include <errno.h> // ENOMEM | ||
| #include <stddef.h> // NULL, size_t | ||
| #include <stdint.h> // int32_t, uint32_t | ||
| #include <sys/types.h> // gid_t, uid_t | ||
|
|
||
| #include <glib.h> // g_byte_array_free, TRUE | ||
| #include <libxml/tree.h> // xmlNode | ||
| #include <qb/qbipcs.h> // qb_ipcs_connection_t | ||
|
|
||
| #include <crm/common/internal.h> // pcmk__client_t, pcmk__find_client | ||
| #include <crm/common/ipc.h> // crm_ipc_client_response | ||
| #include <crm/common/logging.h> // CRM_CHECK | ||
| #include <crm/common/results.h> // pcmk_rc_*, pcmk_rc_str | ||
|
|
||
| #include "pacemaker-execd.h" // client_disconnect_cleanup | ||
|
|
||
| static qb_ipcs_service_t *ipcs = NULL; | ||
clumens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Accept a new client IPC connection | ||
| * | ||
| * \param[in,out] c New connection | ||
| * \param[in] uid Client user id | ||
| * \param[in] gid Client group id | ||
| * | ||
| * \return 0 on success, -errno otherwise | ||
| */ | ||
| static int32_t | ||
| execd_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) | ||
| { | ||
| pcmk__trace("New client connection %p", c); | ||
| if (pcmk__new_client(c, uid, gid) == NULL) { | ||
| return -ENOMEM; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Handle a newly created connection | ||
| * | ||
| * \param[in,out] c New connection | ||
| */ | ||
| static void | ||
| execd_ipc_created(qb_ipcs_connection_t *c) | ||
| { | ||
| pcmk__client_t *new_client = pcmk__find_client(c); | ||
|
|
||
| pcmk__trace("New client connection %p", c); | ||
| pcmk__assert(new_client != NULL); | ||
| /* Now that the connection is offically established, alert | ||
| * the other clients a new connection exists. */ | ||
|
|
||
| notify_of_new_client(new_client); | ||
| } | ||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Destroy a client IPC connection | ||
| * | ||
| * \param[in] c Connection to destroy | ||
| * | ||
| * \return 0 (i.e. do not re-run this callback) | ||
| */ | ||
| static int32_t | ||
| execd_ipc_closed(qb_ipcs_connection_t *c) | ||
| { | ||
| pcmk__client_t *client = pcmk__find_client(c); | ||
|
|
||
| if (client == NULL) { | ||
| pcmk__trace("Ignoring request to clean up unknown connection %p", c); | ||
| } else { | ||
| pcmk__trace("Cleaning up closed client connection %p", c); | ||
| client_disconnect_cleanup(client->id); | ||
| #ifdef PCMK__COMPILE_REMOTE | ||
| ipc_proxy_remove_provider(client); | ||
| #endif | ||
| lrmd_client_destroy(client); | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Destroy a client IPC connection | ||
| * | ||
| * \param[in] c Connection to destroy | ||
| * | ||
| * \note We handle a destroyed connection the same as a closed one, | ||
| * but we need a separate handler because the return type is different. | ||
| */ | ||
| static void | ||
| execd_ipc_destroy(qb_ipcs_connection_t *c) | ||
| { | ||
| pcmk__trace("Destroying client connection %p", c); | ||
| execd_ipc_closed(c); | ||
| } | ||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Handle a message from an IPC connection | ||
| * | ||
| * \param[in,out] c Established IPC connection | ||
| * \param[in] data The message data read from the connection - this can be | ||
| * a complete IPC message or just a part of one if it's | ||
| * very large | ||
| * \param[size] size Unused | ||
| * | ||
| * \return 0 in all cases | ||
| */ | ||
| static int32_t | ||
| execd_ipc_dispatch(qb_ipcs_connection_t *c, void *data, size_t size) | ||
| { | ||
| int rc = pcmk_rc_ok; | ||
| uint32_t id = 0; | ||
| uint32_t flags = 0; | ||
| pcmk__client_t *client = pcmk__find_client(c); | ||
| xmlNode *msg = NULL; | ||
|
|
||
| // Sanity-check, and parse XML from IPC data | ||
| CRM_CHECK(client != NULL, return 0); | ||
|
|
||
| if (data == NULL) { | ||
| pcmk__debug("No IPC data from PID %d", pcmk__client_pid(c)); | ||
| return 0; | ||
| } | ||
|
|
||
| rc = pcmk__ipc_msg_append(&client->buffer, data); | ||
|
|
||
| if (rc == pcmk_rc_ipc_more) { | ||
| /* We haven't read the complete message yet, so just return. */ | ||
| return 0; | ||
|
|
||
| } else if (rc == pcmk_rc_ok) { | ||
| /* We've read the complete message and there's already a header on | ||
| * the front. Pass it off for processing. | ||
| */ | ||
| msg = pcmk__client_data2xml(client, &id, &flags); | ||
| g_byte_array_free(client->buffer, TRUE); | ||
| client->buffer = NULL; | ||
|
|
||
| } else { | ||
| /* Some sort of error occurred reassembling the message. All we can | ||
| * do is clean up, log an error and return. | ||
| */ | ||
| pcmk__err("Error when reading IPC message: %s", pcmk_rc_str(rc)); | ||
|
|
||
| if (client->buffer != NULL) { | ||
| g_byte_array_free(client->buffer, TRUE); | ||
| client->buffer = NULL; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| CRM_CHECK(pcmk__is_set(flags, crm_ipc_client_response), goto done); | ||
|
|
||
| if ((msg == NULL) || execd_invalid_msg(msg)) { | ||
| pcmk__debug("Unrecognizable IPC data from PID %d", pcmk__client_pid(c)); | ||
clumens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| pcmk__ipc_send_ack(client, id, flags, PCMK__XE_NACK, NULL, CRM_EX_PROTOCOL); | ||
| } else { | ||
| pcmk__request_t request = { | ||
| .ipc_client = client, | ||
| .ipc_id = id, | ||
| .ipc_flags = flags, | ||
| .peer = NULL, | ||
| .xml = msg, | ||
| .call_options = 0, | ||
| .result = PCMK__UNKNOWN_RESULT, | ||
| }; | ||
|
|
||
| request.op = pcmk__xe_get_copy(request.xml, PCMK__XA_LRMD_OP); | ||
| CRM_CHECK(request.op != NULL, goto done); | ||
|
|
||
| execd_handle_request(&request); | ||
| } | ||
|
|
||
| done: | ||
| pcmk__xml_free(msg); | ||
| return 0; | ||
| } | ||
|
|
||
| static struct qb_ipcs_service_handlers ipc_callbacks = { | ||
| .connection_accept = execd_ipc_accept, | ||
| .connection_created = execd_ipc_created, | ||
| .msg_process = execd_ipc_dispatch, | ||
| .connection_closed = execd_ipc_closed, | ||
| .connection_destroyed = execd_ipc_destroy | ||
| }; | ||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Clean up executor IPC communication | ||
| */ | ||
| void | ||
| execd_ipc_cleanup(void) | ||
clumens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| if (ipcs != NULL) { | ||
| pcmk__drop_all_clients(ipcs); | ||
| g_clear_pointer(&ipcs, qb_ipcs_destroy); | ||
| } | ||
|
|
||
| pcmk__client_cleanup(); | ||
clumens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /*! | ||
| * \internal | ||
| * \brief Set up executor IPC communication | ||
| */ | ||
| void | ||
| execd_ipc_init(void) | ||
| { | ||
| pcmk__serve_execd_ipc(&ipcs, &ipc_callbacks); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.