pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_verify.c
Go to the documentation of this file.
1/*
2 * Copyright 2023-2024 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
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>
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
24
25int
26pcmk__parse_cib(pcmk__output_t *out, const char *cib_source, xmlNodePtr *cib_object)
27{
28 // @COMPAT Take an enum for cib_source instead of trying to figure it out?
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
49int
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;
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.",
83 goto verify_done;
84 }
85
86 /* Process the configuration to set crm_config_error/crm_config_warning.
87 *
88 * @TODO Some parts of the configuration are unpacked only when needed (for
89 * example, action configuration), so we aren't necessarily checking those.
90 */
91 if (*cib_object != NULL) {
93
94 if (status == NULL) {
95 // No status available, so do minimal checks
97 }
98 cib_object_copy = pcmk__xml_copy(NULL, *cib_object);
99
100 /* The scheduler takes ownership of the XML object and potentially
101 * frees it later. We want the caller of pcmk__verify to retain
102 * ownership of the passed-in XML object, hence we pass in a copy
103 * to the scheduler.
104 */
105 pcmk__schedule_actions(cib_object_copy, flags, scheduler);
106 }
107
108verify_done:
109 if (crm_config_error) {
111 pcmk__config_err("CIB did not pass schema validation");
112 } else if (crm_config_warning) {
114 }
115 return rc;
116}
117
118int
119pcmk_verify(xmlNodePtr *xml, const char *cib_source)
120{
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
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
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
151done:
154 free_xml(cib_object);
155 return rc;
156}
int cib__signon_query(pcmk__output_t *out, cib_t **cib, xmlNode **cib_object)
Definition cib_utils.c:965
xmlNode * pcmk_find_cib_element(xmlNode *cib, const char *element_name)
Find an element in the CIB.
Definition cib.c:172
uint64_t flags
Definition remote.c:3
#define crm_info(fmt, args...)
Definition logging.h:397
gboolean crm_config_warning
Definition utils.c:49
gboolean crm_config_error
Definition utils.c:48
#define pcmk__config_err(fmt...)
pcmk_scheduler_t * scheduler
Control output from tools.
void pcmk__xml_output_finish(pcmk__output_t *out, crm_exit_t exit_status, xmlNodePtr *xml)
Definition output.c:271
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
Definition output.c:244
High Level API.
int pcmk__verify(pcmk_scheduler_t *scheduler, pcmk__output_t *out, xmlNode **cib_object)
Definition pcmk_verify.c:50
int pcmk_verify(xmlNodePtr *xml, const char *cib_source)
Verify that a CIB is error-free or output errors and warnings.
int pcmk__parse_cib(pcmk__output_t *out, const char *cib_source, xmlNodePtr *cib_object)
Definition pcmk_verify.c:26
void pcmk__register_lib_messages(pcmk__output_t *out)
void pcmk__schedule_actions(xmlNode *cib, unsigned long long flags, pcmk_scheduler_t *scheduler)
void pe__register_messages(pcmk__output_t *out)
Definition pe_output.c:3440
#define ENODATA
Function and executable result codes.
#define CRM_ASSERT(expr)
Definition results.h:42
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:501
@ pcmk_rc_ok
Definition results.h:162
@ pcmk_rc_schema_validation
Definition results.h:141
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition results.c:702
Scheduler API.
@ pcmk_sched_no_compat
Definition scheduler.h:170
@ pcmk_sched_no_counts
Definition scheduler.h:164
@ pcmk_sched_validate_only
Definition scheduler.h:183
bool pcmk__validate_xml(xmlNode *xml_blob, const char *validation, xmlRelaxNGValidityErrorFunc error_handler, void *error_handler_context)
Definition schemas.c:757
const char * pcmk__highest_schema_name(void)
Definition schemas.c:97
int pcmk__update_configured_schema(xmlNode **xml, bool to_logs)
Update XML from its configured schema to the latest major series.
Definition schemas.c:1257
void pe_free_working_set(pcmk_scheduler_t *scheduler)
Free scheduler data.
Definition status.c:50
pcmk_scheduler_t * pe_new_working_set(void)
Create a new object to hold scheduler data.
Definition status.c:34
This structure contains everything that makes up a single output formatter.
int(*) int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
void free_xml(xmlNode *child)
Definition xml.c:867
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
Definition xml.c:883
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition xml.c:720
xmlNode * pcmk__xml_read(const char *filename)
Definition xml_io.c:166
xmlNode * pcmk__xml_parse(const char *input)
Definition xml_io.c:244
#define PCMK_XE_CIB
Definition xml_names.h:79
#define PCMK_XE_STATUS
Definition xml_names.h:199