This source file includes following definitions.
- pcmk__parse_cib
- pcmk__verify
- pcmk_verify
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/cib/internal.h>
12 #include <crm/common/output.h>
13 #include <crm/common/results.h>
14 #include <crm/common/scheduler.h>
15 #include <pacemaker-internal.h>
16 #include <pacemaker.h>
17
18 #include <stdint.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include "libpacemaker_private.h"
24
25 int
26 pcmk__parse_cib(pcmk__output_t *out, const char *cib_source, xmlNodePtr *cib_object)
27 {
28
29 const char *first = cib_source;
30
31 if (cib_source == NULL) {
32 crm_info("Reading XML from: live cluster");
33 return cib__signon_query(out, NULL, cib_object);
34 }
35
36 while (isspace(*first)) {
37 first++;
38 }
39
40 if (*first == '<') {
41 *cib_object = pcmk__xml_parse(cib_source);
42 } else {
43 *cib_object = pcmk__xml_read(cib_source);
44 }
45
46 return (*cib_object == NULL)? ENODATA : pcmk_rc_ok;
47 }
48
49 int
50 pcmk__verify(pcmk_scheduler_t *scheduler, pcmk__output_t *out,
51 xmlNode **cib_object)
52 {
53 int rc = pcmk_rc_ok;
54 xmlNode *status = NULL;
55 xmlNode *cib_object_copy = NULL;
56
57 CRM_ASSERT(cib_object != NULL);
58
59 if (!pcmk__xe_is(*cib_object, PCMK_XE_CIB)) {
60 rc = EBADMSG;
61 out->err(out, "This tool can only check complete configurations (i.e. those starting with <cib>).");
62 goto verify_done;
63 }
64
65 status = pcmk_find_cib_element(*cib_object, PCMK_XE_STATUS);
66 if (status == NULL) {
67 pcmk__xe_create(*cib_object, PCMK_XE_STATUS);
68 }
69
70 if (!pcmk__validate_xml(*cib_object, NULL,
71 (xmlRelaxNGValidityErrorFunc) out->err, out)) {
72 crm_config_error = TRUE;
73 rc = pcmk_rc_schema_validation;
74 goto verify_done;
75 }
76
77 rc = pcmk__update_configured_schema(cib_object, false);
78 if (rc != pcmk_rc_ok) {
79 crm_config_error = TRUE;
80 out->err(out, "The cluster will NOT be able to use this configuration.\n"
81 "Please manually update the configuration to conform to the %s syntax.",
82 pcmk__highest_schema_name());
83 goto verify_done;
84 }
85
86
87
88
89
90
91 if (*cib_object != NULL) {
92 unsigned long long flags = pcmk_sched_no_counts|pcmk_sched_no_compat;
93
94 if (status == NULL) {
95
96 flags |= pcmk_sched_validate_only;
97 }
98 cib_object_copy = pcmk__xml_copy(NULL, *cib_object);
99
100
101
102
103
104
105 pcmk__schedule_actions(cib_object_copy, flags, scheduler);
106 }
107
108 verify_done:
109 if (crm_config_error) {
110 rc = pcmk_rc_schema_validation;
111 pcmk__config_err("CIB did not pass schema validation");
112 } else if (crm_config_warning) {
113 rc = pcmk_rc_schema_validation;
114 }
115 return rc;
116 }
117
118 int
119 pcmk_verify(xmlNodePtr *xml, const char *cib_source)
120 {
121 pcmk_scheduler_t *scheduler = NULL;
122 pcmk__output_t *out = NULL;
123 int rc = pcmk_rc_ok;
124
125 xmlNode *cib_object = NULL;
126
127 rc = pcmk__xml_output_new(&out, xml);
128 if (rc != pcmk_rc_ok) {
129 return rc;
130 }
131
132 pe__register_messages(out);
133 pcmk__register_lib_messages(out);
134
135 rc = pcmk__parse_cib(out, cib_source, &cib_object);
136 if (rc != pcmk_rc_ok) {
137 out->err(out, "Couldn't parse input");
138 goto done;
139 }
140
141 scheduler = pe_new_working_set();
142 if (scheduler == NULL) {
143 rc = errno;
144 out->err(out, "Couldn't allocate scheduler data: %s", pcmk_rc_str(rc));
145 goto done;
146 }
147
148 scheduler->priv = out;
149 rc = pcmk__verify(scheduler, out, &cib_object);
150
151 done:
152 pe_free_working_set(scheduler);
153 pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
154 free_xml(cib_object);
155 return rc;
156 }