This source file includes following definitions.
- pcmk_handle_ping_request
- pcmk_handle_shutdown_request
- pcmk_ipc_accept
- pcmk_ipc_closed
- pcmk_ipc_destroy
- pcmk_ipc_dispatch
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include "pacemakerd.h"
12
13 #include <crm/msg_xml.h>
14
15 #include <errno.h>
16 #include <stdbool.h>
17 #include <stdint.h>
18 #include <string.h>
19 #include <time.h>
20 #include <sys/types.h>
21
22 void
23 pcmk_handle_ping_request(pcmk__client_t *c, xmlNode *msg, uint32_t id)
24 {
25 const char *value = NULL;
26 xmlNode *ping = NULL;
27 xmlNode *reply = NULL;
28 const char *from = crm_element_value(msg, F_CRM_SYS_FROM);
29
30
31 crm_trace("Pinged from %s.%s",
32 crm_str(crm_element_value(msg, F_CRM_ORIGIN)),
33 from?from:"unknown");
34 ping = create_xml_node(NULL, XML_CRM_TAG_PING);
35 value = crm_element_value(msg, F_CRM_SYS_TO);
36 crm_xml_add(ping, XML_PING_ATTR_SYSFROM, value);
37 crm_xml_add(ping, XML_PING_ATTR_PACEMAKERDSTATE, pacemakerd_state);
38 crm_xml_add_ll(ping, XML_ATTR_TSTAMP,
39 (long long) subdaemon_check_progress);
40 crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok");
41 reply = create_reply(msg, ping);
42 free_xml(ping);
43 if (reply) {
44 if (pcmk__ipc_send_xml(c, id, reply, crm_ipc_server_event) !=
45 pcmk_rc_ok) {
46 crm_err("Failed sending ping reply to client %s",
47 pcmk__client_name(c));
48 }
49 free_xml(reply);
50 } else {
51 crm_err("Failed building ping reply for client %s",
52 pcmk__client_name(c));
53 }
54
55 if (from && strstr(from, "sbd")) {
56 if (pcmk__str_eq(pacemakerd_state, XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE, pcmk__str_none)) {
57 if (pcmk__get_sbd_sync_resource_startup()) {
58 crm_notice("Shutdown-complete-state passed to SBD.");
59 }
60 shutdown_complete_state_reported_to = c->pid;
61 } else if (pcmk__str_eq(pacemakerd_state, XML_PING_ATTR_PACEMAKERDSTATE_WAITPING, pcmk__str_none)) {
62 crm_notice("Received startup-trigger from SBD.");
63 pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS;
64 mainloop_set_trigger(startup_trigger);
65 }
66 }
67 }
68
69 void
70 pcmk_handle_shutdown_request(pcmk__client_t *c, xmlNode *msg, uint32_t id, uint32_t flags)
71 {
72 xmlNode *shutdown = NULL;
73 xmlNode *reply = NULL;
74
75
76
77
78
79 bool allowed = pcmk_is_set(c->flags, pcmk__client_privileged);
80
81 shutdown = create_xml_node(NULL, XML_CIB_ATTR_SHUTDOWN);
82
83 if (allowed) {
84 crm_notice("Shutting down in response to IPC request %s from %s",
85 crm_element_value(msg, F_CRM_REFERENCE),
86 crm_element_value(msg, F_CRM_ORIGIN));
87 crm_xml_add_int(shutdown, XML_LRM_ATTR_OPSTATUS, CRM_EX_OK);
88 } else {
89 crm_warn("Ignoring shutdown request from unprivileged client %s",
90 pcmk__client_name(c));
91 crm_xml_add_int(shutdown, XML_LRM_ATTR_OPSTATUS, CRM_EX_INSUFFICIENT_PRIV);
92 }
93
94 reply = create_reply(msg, shutdown);
95 free_xml(shutdown);
96 if (reply) {
97 if (pcmk__ipc_send_xml(c, id, reply, crm_ipc_server_event) != pcmk_rc_ok) {
98 crm_err("Failed sending shutdown reply to client %s",
99 pcmk__client_name(c));
100 }
101 free_xml(reply);
102 } else {
103 crm_err("Failed building shutdown reply for client %s",
104 pcmk__client_name(c));
105 }
106
107 if (allowed) {
108 pcmk_shutdown(15);
109 }
110 }
111
112 static int32_t
113 pcmk_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
114 {
115 crm_trace("Connection %p", c);
116 if (pcmk__new_client(c, uid, gid) == NULL) {
117 return -EIO;
118 }
119 return 0;
120 }
121
122
123 static int32_t
124 pcmk_ipc_closed(qb_ipcs_connection_t * c)
125 {
126 pcmk__client_t *client = pcmk__find_client(c);
127
128 if (client == NULL) {
129 return 0;
130 }
131 crm_trace("Connection %p", c);
132 if (shutdown_complete_state_reported_to == client->pid) {
133 shutdown_complete_state_reported_client_closed = TRUE;
134 if (shutdown_trigger) {
135 mainloop_set_trigger(shutdown_trigger);
136 }
137 }
138 pcmk__free_client(client);
139 return 0;
140 }
141
142 static void
143 pcmk_ipc_destroy(qb_ipcs_connection_t * c)
144 {
145 crm_trace("Connection %p", c);
146 pcmk_ipc_closed(c);
147 }
148
149
150 static int32_t
151 pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
152 {
153 uint32_t id = 0;
154 uint32_t flags = 0;
155 const char *task = NULL;
156 xmlNode *msg = NULL;
157 pcmk__client_t *c = pcmk__find_client(qbc);
158
159 CRM_CHECK(c != NULL, return 0);
160
161 msg = pcmk__client_data2xml(c, data, &id, &flags);
162 if (msg == NULL) {
163 pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_PROTOCOL);
164 return 0;
165 }
166
167 task = crm_element_value(msg, F_CRM_TASK);
168 if (pcmk__str_eq(task, CRM_OP_QUIT, pcmk__str_none)) {
169 pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INDETERMINATE);
170 pcmk_handle_shutdown_request(c, msg, id, flags);
171
172 } else if (pcmk__str_eq(task, CRM_OP_RM_NODE_CACHE, pcmk__str_none)) {
173 crm_trace("Ignoring request from client %s to purge node "
174 "because peer cache is not used", pcmk__client_name(c));
175 pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_OK);
176
177 } else if (pcmk__str_eq(task, CRM_OP_PING, pcmk__str_none)) {
178 pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INDETERMINATE);
179 pcmk_handle_ping_request(c, msg, id);
180
181 } else {
182 crm_debug("Unrecognized IPC command '%s' from client %s",
183 crm_str(task), pcmk__client_name(c));
184 pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INVALID_PARAM);
185 }
186
187 free_xml(msg);
188 return 0;
189 }
190
191 struct qb_ipcs_service_handlers mcp_ipc_callbacks = {
192 .connection_accept = pcmk_ipc_accept,
193 .connection_created = NULL,
194 .msg_process = pcmk_ipc_dispatch,
195 .connection_closed = pcmk_ipc_closed,
196 .connection_destroyed = pcmk_ipc_destroy
197 };