This source file includes following definitions.
- cli_resource_print_cts_constraints
- cli_resource_print_cts
- cli_resource_print_raw
- cli_resource_print_list
- cli_resource_print_operations
- cli_resource_print_location
- cli_resource_print_colocation
- cli_resource_print
- cli_resource_print_attribute
- cli_resource_print_property
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <crm_resource.h>
21
22 bool print_pending = TRUE;
23
24 #define cons_string(x) x?x:"NA"
25 void
26 cli_resource_print_cts_constraints(pe_working_set_t * data_set)
27 {
28 xmlNode *xml_obj = NULL;
29 xmlNode *lifetime = NULL;
30 xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set->input);
31
32 for (xml_obj = __xml_first_child(cib_constraints); xml_obj != NULL;
33 xml_obj = __xml_next(xml_obj)) {
34 const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
35
36 if (id == NULL) {
37 continue;
38 }
39
40 lifetime = first_named_child(xml_obj, "lifetime");
41
42 if (test_ruleset(lifetime, NULL, data_set->now) == FALSE) {
43 continue;
44 }
45
46 if (safe_str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj))) {
47 printf("Constraint %s %s %s %s %s %s %s\n",
48 crm_element_name(xml_obj),
49 cons_string(crm_element_value(xml_obj, XML_ATTR_ID)),
50 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE)),
51 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET)),
52 cons_string(crm_element_value(xml_obj, XML_RULE_ATTR_SCORE)),
53 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE)),
54 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE)));
55
56 } else if (safe_str_eq(XML_CONS_TAG_RSC_LOCATION, crm_element_name(xml_obj))) {
57
58 }
59 }
60 }
61
62 void
63 cli_resource_print_cts(resource_t * rsc)
64 {
65 GListPtr lpc = NULL;
66 const char *host = NULL;
67 bool needs_quorum = TRUE;
68 const char *rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
69 const char *rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
70 const char *rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
71
72 if (safe_str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH)) {
73 xmlNode *op = NULL;
74
75 needs_quorum = FALSE;
76
77 for (op = __xml_first_child(rsc->ops_xml); op != NULL; op = __xml_next(op)) {
78 if (crm_str_eq((const char *)op->name, "op", TRUE)) {
79 const char *name = crm_element_value(op, "name");
80
81 if (safe_str_neq(name, CRMD_ACTION_START)) {
82 const char *value = crm_element_value(op, "requires");
83
84 if (safe_str_eq(value, "nothing")) {
85 needs_quorum = FALSE;
86 }
87 break;
88 }
89 }
90 }
91 }
92
93 if (rsc->running_on != NULL && g_list_length(rsc->running_on) == 1) {
94 node_t *tmp = rsc->running_on->data;
95
96 host = tmp->details->uname;
97 }
98
99 printf("Resource: %s %s %s %s %s %s %s %s %d %lld 0x%.16llx\n",
100 crm_element_name(rsc->xml), rsc->id,
101 rsc->clone_name ? rsc->clone_name : rsc->id, rsc->parent ? rsc->parent->id : "NA",
102 rprov ? rprov : "NA", rclass, rtype, host ? host : "NA", needs_quorum, rsc->flags,
103 rsc->flags);
104
105 for (lpc = rsc->children; lpc != NULL; lpc = lpc->next) {
106 resource_t *child = (resource_t *) lpc->data;
107
108 cli_resource_print_cts(child);
109 }
110 }
111
112
113 void
114 cli_resource_print_raw(resource_t * rsc)
115 {
116 GListPtr lpc = NULL;
117 GListPtr children = rsc->children;
118
119 if (children == NULL) {
120 printf("%s\n", rsc->id);
121 }
122
123 for (lpc = children; lpc != NULL; lpc = lpc->next) {
124 resource_t *child = (resource_t *) lpc->data;
125
126 cli_resource_print_raw(child);
127 }
128 }
129
130 int
131 cli_resource_print_list(pe_working_set_t * data_set, bool raw)
132 {
133 int found = 0;
134
135 GListPtr lpc = NULL;
136 int opts = pe_print_printf | pe_print_rsconly;
137
138 if (print_pending) {
139 opts |= pe_print_pending;
140 }
141
142 for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) {
143 resource_t *rsc = (resource_t *) lpc->data;
144
145 if (is_set(rsc->flags, pe_rsc_orphan)
146 && rsc->fns->active(rsc, TRUE) == FALSE) {
147 continue;
148 }
149 rsc->fns->print(rsc, NULL, opts, stdout);
150 found++;
151 }
152
153 if (found == 0) {
154 printf("NO resources configured\n");
155 return -ENXIO;
156 }
157
158 return 0;
159 }
160
161 int
162 cli_resource_print_operations(const char *rsc_id, const char *host_uname, bool active,
163 pe_working_set_t * data_set)
164 {
165 resource_t *rsc = NULL;
166 int opts = pe_print_printf | pe_print_rsconly | pe_print_suppres_nl;
167 GListPtr ops = find_operations(rsc_id, host_uname, active, data_set);
168 GListPtr lpc = NULL;
169
170 if (print_pending) {
171 opts |= pe_print_pending;
172 }
173
174 for (lpc = ops; lpc != NULL; lpc = lpc->next) {
175 xmlNode *xml_op = (xmlNode *) lpc->data;
176
177 const char *op_rsc = crm_element_value(xml_op, "resource");
178 const char *last = crm_element_value(xml_op, XML_RSC_OP_LAST_CHANGE);
179 const char *status_s = crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS);
180 const char *op_key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY);
181 int status = crm_parse_int(status_s, "0");
182
183 rsc = pe_find_resource(data_set->resources, op_rsc);
184 if(rsc) {
185 rsc->fns->print(rsc, "", opts, stdout);
186 } else {
187 fprintf(stdout, "Unknown resource %s", op_rsc);
188 }
189
190 fprintf(stdout, ": %s (node=%s, call=%s, rc=%s",
191 op_key ? op_key : ID(xml_op),
192 crm_element_value(xml_op, XML_ATTR_UNAME),
193 crm_element_value(xml_op, XML_LRM_ATTR_CALLID),
194 crm_element_value(xml_op, XML_LRM_ATTR_RC));
195 if (last) {
196 time_t run_at = crm_parse_int(last, "0");
197
198 fprintf(stdout, ", last-rc-change=%s, exec=%sms",
199 crm_strip_trailing_newline(ctime(&run_at)), crm_element_value(xml_op, XML_RSC_OP_T_EXEC));
200 }
201 fprintf(stdout, "): %s\n", services_lrm_status_str(status));
202 }
203 return pcmk_ok;
204 }
205
206 void
207 cli_resource_print_location(resource_t * rsc, const char *prefix)
208 {
209 GListPtr lpc = NULL;
210 GListPtr list = rsc->rsc_location;
211 int offset = 0;
212
213 if (prefix) {
214 offset = strlen(prefix) - 2;
215 }
216
217 for (lpc = list; lpc != NULL; lpc = lpc->next) {
218 rsc_to_node_t *cons = (rsc_to_node_t *) lpc->data;
219
220 GListPtr lpc2 = NULL;
221
222 for (lpc2 = cons->node_list_rh; lpc2 != NULL; lpc2 = lpc2->next) {
223 node_t *node = (node_t *) lpc2->data;
224 char *score = score2char(node->weight);
225
226 fprintf(stdout, "%s: Node %-*s (score=%s, id=%s)\n",
227 prefix ? prefix : " ", 71 - offset, node->details->uname, score, cons->id);
228 free(score);
229 }
230 }
231 }
232
233 void
234 cli_resource_print_colocation(resource_t * rsc, bool dependents, bool recursive, int offset)
235 {
236 char *prefix = NULL;
237 GListPtr lpc = NULL;
238 GListPtr list = rsc->rsc_cons;
239
240 prefix = calloc(1, (offset * 4) + 1);
241 memset(prefix, ' ', offset * 4);
242
243 if (dependents) {
244 list = rsc->rsc_cons_lhs;
245 }
246
247 if (is_set(rsc->flags, pe_rsc_allocating)) {
248
249 printf("loop %s\n", rsc->id);
250 free(prefix);
251 return;
252 }
253
254 set_bit(rsc->flags, pe_rsc_allocating);
255 for (lpc = list; lpc != NULL; lpc = lpc->next) {
256 rsc_colocation_t *cons = (rsc_colocation_t *) lpc->data;
257
258 char *score = NULL;
259 resource_t *peer = cons->rsc_rh;
260
261 if (dependents) {
262 peer = cons->rsc_lh;
263 }
264
265 if (is_set(peer->flags, pe_rsc_allocating)) {
266 if (dependents == FALSE) {
267 fprintf(stdout, "%s%-*s (id=%s - loop)\n", prefix, 80 - (4 * offset), peer->id,
268 cons->id);
269 }
270 continue;
271 }
272
273 if (dependents && recursive) {
274 cli_resource_print_colocation(peer, dependents, recursive, offset + 1);
275 }
276
277 score = score2char(cons->score);
278 if (cons->role_rh > RSC_ROLE_STARTED) {
279 fprintf(stdout, "%s%-*s (score=%s, %s role=%s, id=%s)\n", prefix, 80 - (4 * offset),
280 peer->id, score, dependents ? "needs" : "with", role2text(cons->role_rh),
281 cons->id);
282 } else {
283 fprintf(stdout, "%s%-*s (score=%s, id=%s)\n", prefix, 80 - (4 * offset),
284 peer->id, score, cons->id);
285 }
286 cli_resource_print_location(peer, prefix);
287 free(score);
288
289 if (!dependents && recursive) {
290 cli_resource_print_colocation(peer, dependents, recursive, offset + 1);
291 }
292 }
293 free(prefix);
294 }
295
296 int
297 cli_resource_print(resource_t *rsc, pe_working_set_t *data_set, bool expanded)
298 {
299 char *rsc_xml = NULL;
300 int opts = pe_print_printf;
301
302 if (print_pending) {
303 opts |= pe_print_pending;
304 }
305 rsc->fns->print(rsc, NULL, opts, stdout);
306
307 rsc_xml = dump_xml_formatted((!expanded && rsc->orig_xml)?
308 rsc->orig_xml : rsc->xml);
309 fprintf(stdout, "%sxml:\n%s\n", expanded ? "" : "raw ", rsc_xml);
310 free(rsc_xml);
311 return 0;
312 }
313
314 int
315 cli_resource_print_attribute(resource_t *rsc, const char *attr, pe_working_set_t * data_set)
316 {
317 int rc = -ENXIO;
318 node_t *current = NULL;
319 GHashTable *params = NULL;
320 const char *value = NULL;
321
322 if (g_list_length(rsc->running_on) == 1) {
323 current = rsc->running_on->data;
324
325 } else if (g_list_length(rsc->running_on) > 1) {
326 CMD_ERR("%s is active on more than one node,"
327 " returning the default value for %s", rsc->id, crm_str(attr));
328 }
329
330 params = crm_str_table_new();
331
332 if (safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) {
333 get_rsc_attributes(params, rsc, current, data_set);
334
335 } else if (safe_str_eq(attr_set_type, XML_TAG_META_SETS)) {
336
337 get_meta_attributes(params, rsc, current, data_set);
338
339 } else {
340 unpack_instance_attributes(data_set->input, rsc->xml,
341 XML_TAG_UTILIZATION, NULL,
342 params, NULL, FALSE, data_set->now);
343 }
344
345 crm_debug("Looking up %s in %s", attr, rsc->id);
346 value = g_hash_table_lookup(params, attr);
347 if (value != NULL) {
348 fprintf(stdout, "%s\n", value);
349 rc = 0;
350
351 } else {
352 CMD_ERR("Attribute '%s' not found for '%s'", attr, rsc->id);
353 }
354
355 g_hash_table_destroy(params);
356 return rc;
357 }
358
359
360 int
361 cli_resource_print_property(resource_t *rsc, const char *attr, pe_working_set_t * data_set)
362 {
363 const char *value = crm_element_value(rsc->xml, attr);
364
365 if (value != NULL) {
366 fprintf(stdout, "%s\n", value);
367 return 0;
368 }
369 return -ENXIO;
370 }