This source file includes following definitions.
- pe__resource_contains_guest_node
- xml_contains_remote_node
- pe_foreach_guest_node
- pe_create_remote_xml
- pe__add_param_check
- pe__foreach_param_check
- pe__free_param_checks
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/common/xml.h>
12 #include <crm/common/scheduler_internal.h>
13 #include <crm/pengine/internal.h>
14 #include <glib.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28 pcmk_resource_t *
29 pe__resource_contains_guest_node(const pcmk_scheduler_t *scheduler,
30 const pcmk_resource_t *rsc)
31 {
32 if ((rsc != NULL) && (scheduler != NULL)
33 && pcmk_is_set(scheduler->flags, pcmk__sched_have_remote_nodes)) {
34
35 for (GList *gIter = rsc->priv->launched;
36 gIter != NULL; gIter = gIter->next) {
37
38 pcmk_resource_t *launched = gIter->data;
39
40 if (pcmk_is_set(launched->flags, pcmk__rsc_is_remote_connection)) {
41 return launched;
42 }
43 }
44 }
45 return NULL;
46 }
47
48 bool
49 xml_contains_remote_node(xmlNode *xml)
50 {
51 const char *value = NULL;
52
53 if (xml == NULL) {
54 return false;
55 }
56
57 value = crm_element_value(xml, PCMK_XA_TYPE);
58 if (!pcmk__str_eq(value, "remote", pcmk__str_casei)) {
59 return false;
60 }
61
62 value = crm_element_value(xml, PCMK_XA_CLASS);
63 if (!pcmk__str_eq(value, PCMK_RESOURCE_CLASS_OCF, pcmk__str_casei)) {
64 return false;
65 }
66
67 value = crm_element_value(xml, PCMK_XA_PROVIDER);
68 if (!pcmk__str_eq(value, "pacemaker", pcmk__str_casei)) {
69 return false;
70 }
71
72 return true;
73 }
74
75
76
77
78
79
80
81
82
83
84 void
85 pe_foreach_guest_node(const pcmk_scheduler_t *scheduler,
86 const pcmk_node_t *host,
87 void (*helper)(const pcmk_node_t*, void*),
88 void *user_data)
89 {
90 GList *iter;
91
92 CRM_CHECK(scheduler && host && host->details && helper, return);
93 if (!pcmk_is_set(scheduler->flags, pcmk__sched_have_remote_nodes)) {
94 return;
95 }
96 for (iter = host->details->running_rsc; iter != NULL; iter = iter->next) {
97 pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
98
99 if (pcmk_is_set(rsc->flags, pcmk__rsc_is_remote_connection)
100 && (rsc->priv->launcher != NULL)) {
101 pcmk_node_t *guest_node = pcmk_find_node(scheduler, rsc->id);
102
103 if (guest_node) {
104 (*helper)(guest_node, user_data);
105 }
106 }
107 }
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 xmlNode *
128 pe_create_remote_xml(xmlNode *parent, const char *uname,
129 const char *container_id, const char *migrateable,
130 const char *is_managed, const char *start_timeout,
131 const char *server, const char *port)
132 {
133 xmlNode *remote;
134 xmlNode *xml_sub;
135
136 remote = pcmk__xe_create(parent, PCMK_XE_PRIMITIVE);
137
138
139 crm_xml_add(remote, PCMK_XA_ID, uname);
140 crm_xml_add(remote, PCMK_XA_CLASS, PCMK_RESOURCE_CLASS_OCF);
141 crm_xml_add(remote, PCMK_XA_PROVIDER, "pacemaker");
142 crm_xml_add(remote, PCMK_XA_TYPE, "remote");
143
144
145 xml_sub = pcmk__xe_create(remote, PCMK_XE_META_ATTRIBUTES);
146 pcmk__xe_set_id(xml_sub, "%s-%s", uname, PCMK_XE_META_ATTRIBUTES);
147 crm_create_nvpair_xml(xml_sub, NULL,
148 PCMK__META_INTERNAL_RSC, PCMK_VALUE_TRUE);
149 if (container_id) {
150 crm_create_nvpair_xml(xml_sub, NULL,
151 PCMK__META_CONTAINER, container_id);
152 }
153 if (migrateable) {
154 crm_create_nvpair_xml(xml_sub, NULL,
155 PCMK_META_ALLOW_MIGRATE, migrateable);
156 }
157 if (is_managed) {
158 crm_create_nvpair_xml(xml_sub, NULL, PCMK_META_IS_MANAGED, is_managed);
159 }
160
161
162 if (port || server) {
163 xml_sub = pcmk__xe_create(remote, PCMK_XE_INSTANCE_ATTRIBUTES);
164 pcmk__xe_set_id(xml_sub, "%s-%s", uname, PCMK_XE_INSTANCE_ATTRIBUTES);
165 if (server) {
166 crm_create_nvpair_xml(xml_sub, NULL, PCMK_REMOTE_RA_ADDR, server);
167 }
168 if (port) {
169 crm_create_nvpair_xml(xml_sub, NULL, PCMK_REMOTE_RA_PORT, port);
170 }
171 }
172
173
174 xml_sub = pcmk__xe_create(remote, PCMK_XE_OPERATIONS);
175 crm_create_op_xml(xml_sub, uname, PCMK_ACTION_MONITOR, "30s", "30s");
176 if (start_timeout) {
177 crm_create_op_xml(xml_sub, uname, PCMK_ACTION_START, "0",
178 start_timeout);
179 }
180 return remote;
181 }
182
183
184 struct check_op {
185 const xmlNode *rsc_op;
186 pcmk_resource_t *rsc;
187 pcmk_node_t *node;
188 enum pcmk__check_parameters check_type;
189 };
190
191 void
192 pe__add_param_check(const xmlNode *rsc_op, pcmk_resource_t *rsc,
193 pcmk_node_t *node, enum pcmk__check_parameters flag,
194 pcmk_scheduler_t *scheduler)
195 {
196 struct check_op *check_op = NULL;
197
198 CRM_CHECK(scheduler && rsc_op && rsc && node, return);
199
200 check_op = pcmk__assert_alloc(1, sizeof(struct check_op));
201
202 crm_trace("Deferring checks of %s until after allocation",
203 pcmk__xe_id(rsc_op));
204 check_op->rsc_op = rsc_op;
205 check_op->rsc = rsc;
206 check_op->node = node;
207 check_op->check_type = flag;
208 scheduler->priv->param_check = g_list_prepend(scheduler->priv->param_check,
209 check_op);
210 }
211
212
213
214
215
216
217
218
219 void
220 pe__foreach_param_check(pcmk_scheduler_t *scheduler,
221 void (*cb)(pcmk_resource_t*, pcmk_node_t*,
222 const xmlNode*, enum pcmk__check_parameters))
223 {
224 CRM_CHECK(scheduler && cb, return);
225
226 for (GList *item = scheduler->priv->param_check;
227 item != NULL; item = item->next) {
228 struct check_op *check_op = item->data;
229
230 cb(check_op->rsc, check_op->node, check_op->rsc_op,
231 check_op->check_type);
232 }
233 }
234
235 void
236 pe__free_param_checks(pcmk_scheduler_t *scheduler)
237 {
238 if ((scheduler != NULL) && (scheduler->priv->param_check != NULL)) {
239 g_list_free_full(scheduler->priv->param_check, free);
240 scheduler->priv->param_check = NULL;
241 }
242 }