Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1701913
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
32 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/tools/cibadmin.c b/tools/cibadmin.c
index 590319cf88..26c7048bc8 100644
--- a/tools/cibadmin.c
+++ b/tools/cibadmin.c
@@ -1,976 +1,988 @@
/*
* Copyright 2004-2022 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <stdio.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crm/common/ipc.h>
#include <crm/cib/internal.h>
#include <pacemaker-internal.h>
enum cibadmin_section_type {
cibadmin_section_all = 0,
cibadmin_section_scope,
cibadmin_section_xpath,
};
static int message_timeout_sec = 0;
static int command_options = 0;
static int request_id = 0;
static int bump_log_num = 0;
static char *host = NULL;
static const char *cib_user = NULL;
static const char *cib_action = NULL;
static enum cibadmin_section_type section_type = cibadmin_section_all;
static const char *cib_section = NULL;
static cib_t *the_cib = NULL;
static GMainLoop *mainloop = NULL;
static crm_exit_t exit_code = CRM_EX_OK;
int do_init(void);
int do_work(xmlNode *input, int command_options, xmlNode **output);
void cibadmin_op_callback(xmlNode *msg, int call_id, int rc, xmlNode *output,
void *user_data);
static pcmk__cli_option_t long_options[] = {
// long option, argument type, storage, short option, description, flags
{
"help", no_argument, NULL, '?',
"\tThis text", pcmk__option_default
},
{
"version", no_argument, NULL, '$',
"\tVersion information", pcmk__option_default
},
{
"verbose", no_argument, NULL, 'V',
"\tIncrease debug output\n", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"Commands:", pcmk__option_default
},
{
"upgrade", no_argument, NULL, 'u',
"\tUpgrade the configuration to the latest syntax", pcmk__option_default
},
{
"query", no_argument, NULL, 'Q',
"\tQuery the contents of the CIB", pcmk__option_default
},
{
"erase", no_argument, NULL, 'E',
"\tErase the contents of the whole CIB", pcmk__option_default
},
{
"bump", no_argument, NULL, 'B',
"\tIncrease the CIB's epoch value by 1", pcmk__option_default
},
{
"create", no_argument, NULL, 'C',
"\tCreate an object in the CIB (will fail if object already exists)",
pcmk__option_default
},
{
"modify", no_argument, NULL, 'M',
"\tFind object somewhere in CIB's XML tree and update it "
"(fails if object does not exist unless -c is also specified)",
pcmk__option_default
},
{
"patch", no_argument, NULL, 'P',
"\tSupply an update in the form of an XML diff (see crm_diff(8))",
pcmk__option_default
},
{
"replace", no_argument, NULL, 'R',
"\tRecursively replace an object in the CIB", pcmk__option_default
},
{
"delete", no_argument, NULL, 'D',
"\tDelete first object matching supplied criteria "
"(for example, <op id=\"rsc1_op1\" name=\"monitor\"/>)",
pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\n\tThe XML element name and all attributes must match "
"in order for the element to be deleted.\n",
pcmk__option_default
},
{
"delete-all", no_argument, NULL, 'd',
"When used with --xpath, remove all matching objects in the "
"configuration instead of just the first one",
pcmk__option_default
},
{
"empty", no_argument, NULL, 'a',
"\tOutput an empty CIB", pcmk__option_default
},
{
"md5-sum", no_argument, NULL, '5',
"\tCalculate the on-disk CIB digest", pcmk__option_default
},
{
"md5-sum-versioned", no_argument, NULL, '6',
"Calculate an on-the-wire versioned CIB digest", pcmk__option_default
},
{
"show-access", optional_argument, NULL, 'S',
"Whether to use syntax highlighting for ACLs "
"(with -Q/--query and -U/--user)",
pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\n\tThat amounts to one of \"color\" (default for terminal),"
" \"text\" (otherwise), \"namespace\", or \"auto\""
" (per former defaults).",
pcmk__option_default
},
{
"blank", no_argument, NULL, '-',
NULL, pcmk__option_hidden
},
{
"-spacer-", required_argument, NULL, '-',
"\nAdditional options:", pcmk__option_default
},
{
"force", no_argument, NULL, 'f',
NULL, pcmk__option_default
},
{
"timeout", required_argument, NULL, 't',
"Time (in seconds) to wait before declaring the operation failed",
pcmk__option_default
},
{
"user", required_argument, NULL, 'U',
"Run the command with permissions of the named user (valid only for "
"the root and " CRM_DAEMON_USER " accounts)",
pcmk__option_default
},
{
"sync-call", no_argument, NULL, 's',
"Wait for call to complete before returning", pcmk__option_default
},
{
"local", no_argument, NULL, 'l',
"\tCommand takes effect locally (should be used only for queries)",
pcmk__option_default
},
{
"allow-create", no_argument, NULL, 'c',
"(Advanced) Allow target of --modify/-M to be created "
"if it does not exist",
pcmk__option_default
},
{
"no-children", no_argument, NULL, 'n',
"(Advanced) When querying an object, do not include its children "
"in the result",
pcmk__option_default
},
{
"no-bcast", no_argument, NULL, 'b',
NULL, pcmk__option_hidden
},
{
"-spacer-", no_argument, NULL, '-',
"\nData:", pcmk__option_default
},
{
"xml-text", required_argument, NULL, 'X',
"Retrieve XML from the supplied string", pcmk__option_default
},
{
"xml-file", required_argument, NULL, 'x',
"Retrieve XML from the named file", pcmk__option_default
},
{
"xml-pipe", no_argument, NULL, 'p',
"Retrieve XML from stdin\n", pcmk__option_default
},
{
"scope", required_argument, NULL, 'o',
"Limit scope of operation to specific section of CIB",
pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\tValid values: configuration, nodes, resources, constraints, "
"crm_config, rsc_defaults, op_defaults, acls, fencing-topology, "
"tags, alerts",
pcmk__option_default
},
{
"xpath", required_argument, NULL, 'A',
"A valid XPath to use instead of --scope/-o", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\n\tIf both --scope/-o and --xpath/-a are specified, the last one to "
"appear takes effect\n",
pcmk__option_default
},
{
"node-path", no_argument, NULL, 'e',
"When performing XPath queries, return path of any matches found",
pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\t(for example, \"/cib/configuration/resources/clone[@id='ms_RH1_SCS']"
"/primitive[@id='prm_RH1_SCS']\")",
pcmk__option_paragraph
},
{
"node", required_argument, NULL, 'N',
"(Advanced) Send command to the specified host", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '!',
NULL, pcmk__option_hidden
},
{
"-spacer-", no_argument, NULL, '-',
"\n\nExamples:\n", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"Query the configuration from the local node:", pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --query --local", pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Query just the cluster options configuration:", pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --query --scope crm_config", pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Query all 'target-role' settings:", pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --query --xpath \"//nvpair[@name='target-role']\"",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Remove all 'is-managed' settings:", pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --delete-all --xpath \"//nvpair[@name='is-managed']\"",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Remove the resource named 'old':", pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --delete --xml-text '<primitive id=\"old\"/>'",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Remove all resources from the configuration:", pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --replace --scope resources --xml-text '<resources/>'",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Replace complete configuration with contents of $HOME/pacemaker.xml:",
pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --replace --xml-file $HOME/pacemaker.xml",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Replace constraints section of configuration with contents of "
"$HOME/constraints.xml:",
pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --replace --scope constraints --xml-file "
"$HOME/constraints.xml",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Increase configuration version to prevent old configurations from "
"being loaded accidentally:",
pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --modify --xml-text '<cib admin_epoch=\"admin_epoch++\"/>'",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Edit the configuration with your favorite $EDITOR:",
pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --query > $HOME/local.xml", pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
" $EDITOR $HOME/local.xml", pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --replace --xml-file $HOME/local.xml", pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"Assuming terminal, render configuration in color (green for writable, blue for readable, red for denied) to visualize permissions for user tony:",
pcmk__option_paragraph
},
{
"-spacer-", no_argument, NULL, '-',
" cibadmin --show-access=color --query --user tony | less -r",
pcmk__option_example
},
{
"-spacer-", no_argument, NULL, '-',
"SEE ALSO:", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
" crm(8), pcs(8), crm_shadow(8), crm_diff(8)", pcmk__option_default
},
{
"host", required_argument, NULL, 'h',
"deprecated", pcmk__option_hidden
},
{ 0, 0, 0, 0 }
};
static void
print_xml_output(xmlNode * xml)
{
char *buffer;
if (!xml) {
return;
} else if (xml->type != XML_ELEMENT_NODE) {
return;
}
if (command_options & cib_xpath_address) {
const char *id = crm_element_value(xml, XML_ATTR_ID);
if (pcmk__str_eq((const char *)xml->name, "xpath-query", pcmk__str_casei)) {
xmlNode *child = NULL;
for (child = xml->children; child; child = child->next) {
print_xml_output(child);
}
} else if (id) {
printf("%s\n", id);
}
} else {
buffer = dump_xml_formatted(xml);
fprintf(stdout, "%s", pcmk__s(buffer, "<null>\n"));
free(buffer);
}
}
// Upgrade requested but already at latest schema
static void
report_schema_unchanged(void)
{
const char *err = pcmk_rc_str(pcmk_rc_schema_unchanged);
crm_info("Upgrade unnecessary: %s\n", err);
printf("Upgrade unnecessary: %s\n", err);
exit_code = CRM_EX_OK;
}
int
main(int argc, char **argv)
{
int argerr = 0;
int rc = pcmk_ok;
int flag;
const char *source = NULL;
const char *admin_input_xml = NULL;
const char *admin_input_file = NULL;
gboolean dangerous_cmd = FALSE;
gboolean admin_input_stdin = FALSE;
xmlNode *output = NULL;
xmlNode *input = NULL;
- char *username = NULL;
const char *acl_cred = NULL;
enum pcmk__acl_render_how acl_render_mode = pcmk__acl_render_none;
bool allow_create = false;
bool delete_all = false;
bool force = false;
bool get_node_path = false;
bool local = false;
bool no_bcast = false;
bool no_children = false;
bool sync_call = false;
int option_index = 0;
pcmk__cli_init_logging("cibadmin", 0);
set_crm_log_level(LOG_CRIT);
pcmk__set_cli_options(NULL, "<command> [options]", long_options,
"query and edit the Pacemaker configuration");
if (argc < 2) {
pcmk__cli_help('?', CRM_EX_USAGE);
}
while (1) {
flag = pcmk__next_cli_option(argc, argv, &option_index, NULL);
if (flag == -1)
break;
switch (flag) {
case 't':
message_timeout_sec = atoi(optarg);
break;
case 'A':
section_type = cibadmin_section_xpath;
cib_section = optarg;
break;
case 'e':
get_node_path = true;
break;
case 'u':
cib_action = PCMK__CIB_REQUEST_UPGRADE;
dangerous_cmd = TRUE;
break;
case 'E':
cib_action = PCMK__CIB_REQUEST_ERASE;
dangerous_cmd = TRUE;
break;
case 'S':
if (pcmk__str_eq(optarg, "auto", pcmk__str_null_matches)) {
acl_render_mode = pcmk__acl_render_default;
} else if (strcmp(optarg, "namespace") == 0) {
acl_render_mode = pcmk__acl_render_namespace;
} else if (strcmp(optarg, "text") == 0) {
acl_render_mode = pcmk__acl_render_text;
} else if (strcmp(optarg, "color") == 0) {
acl_render_mode = pcmk__acl_render_color;
} else {
fprintf(stderr,
"Unrecognized value for --show-access: '%s'\n",
optarg);
++argerr;
}
break;
case 'Q':
cib_action = PCMK__CIB_REQUEST_QUERY;
break;
case 'P':
cib_action = PCMK__CIB_REQUEST_APPLY_PATCH;
break;
case 'U':
cib_user = optarg;
break;
case 'M':
cib_action = PCMK__CIB_REQUEST_MODIFY;
break;
case 'R':
cib_action = PCMK__CIB_REQUEST_REPLACE;
break;
case 'C':
cib_action = PCMK__CIB_REQUEST_CREATE;
break;
case 'D':
cib_action = PCMK__CIB_REQUEST_DELETE;
delete_all = false;
break;
case '5':
cib_action = "md5-sum";
break;
case '6':
cib_action = "md5-sum-versioned";
break;
case 'c':
allow_create = true;
break;
case 'n':
no_children = true;
break;
case 'B':
cib_action = PCMK__CIB_REQUEST_BUMP;
break;
case 'V':
bump_log_num++;
break;
case '?':
case '$':
case '!':
pcmk__cli_help(flag, CRM_EX_OK);
break;
case 'o':
section_type = cibadmin_section_scope;
cib_section = optarg;
break;
case 'X':
admin_input_xml = optarg;
break;
case 'x':
admin_input_file = optarg;
break;
case 'p':
admin_input_stdin = TRUE;
break;
case 'N':
case 'h':
pcmk__str_update(&host, optarg);
break;
case 'l':
local = true;
break;
case 'd':
cib_action = PCMK__CIB_REQUEST_DELETE;
delete_all = true;
dangerous_cmd = TRUE;
break;
case 'b':
no_bcast = true;
dangerous_cmd = TRUE;
break;
case 's':
sync_call = true;
break;
case 'f':
force = true;
break;
case 'a':
output = createEmptyCib(1);
if (optind < argc) {
crm_xml_add(output, XML_ATTR_VALIDATION, argv[optind]);
}
admin_input_xml = dump_xml_formatted(output);
fprintf(stdout, "%s", pcmk__s(admin_input_xml, "<null>\n"));
- crm_exit(CRM_EX_OK);
- break;
+ goto done;
default:
printf("Argument code 0%o (%c)" " is not (?yet?) supported\n", flag, flag);
++argerr;
break;
}
}
if (bump_log_num > 0) {
cib__set_call_options(command_options, crm_system_name,
cib_verbose);
}
while (bump_log_num > 0) {
crm_bump_log_level(argc, argv);
bump_log_num--;
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
pcmk__cli_help('?', CRM_EX_USAGE);
}
if (optind > argc || cib_action == NULL) {
++argerr;
}
if (argerr) {
pcmk__cli_help('?', CRM_EX_USAGE);
}
if (delete_all
&& (strcmp(options.cib_action, PCMK__CIB_REQUEST_DELETE) != 0)) {
// --delete-all was replaced by some other action besides --delete
delete_all = false;
}
if (dangerous_cmd && !force) {
+ exit_code = CRM_EX_UNSAFE;
fprintf(stderr, "The supplied command is considered dangerous."
" To prevent accidental destruction of the cluster,"
" the --force flag is required in order to proceed.\n");
fflush(stderr);
- crm_exit(CRM_EX_UNSAFE);
+ goto done;
}
if (message_timeout_sec < 1) {
// Set default timeout
message_timeout_sec = 30;
}
if (section_type == cibadmin_section_xpath) {
// Enable getting section by XPath
cib__set_call_options(command_options, crm_system_name,
cib_xpath);
}
if (allow_create) {
// Allow target of --modify/-M to be created if it does not exist
cib__set_call_options(command_options, crm_system_name,
cib_can_create);
}
if (delete_all) {
// With cibadmin_section_xpath, remove all matching objects
cib__set_call_options(command_options, crm_system_name,
cib_multiple);
}
if (force) {
// Perform the action even without quorum
cib__set_call_options(command_options, crm_system_name,
cib_quorum_override);
}
if (get_node_path) {
/* Enable getting node path of XPath query matches.
* Meaningful only if section_type == cibadmin_section_xpath.
*/
cib__set_call_options(command_options, crm_system_name,
cib_xpath_address);
}
if (local) {
// Configure command to take effect only locally
cib__set_call_options(command_options, crm_system_name,
cib_scope_local);
}
// @COMPAT: Deprecated option
if (no_bcast) {
// Configure command to take effect only locally and not to broadcast
cib__set_call_options(command_options, crm_system_name,
cib_inhibit_bcast|cib_scope_local);
}
if (no_children) {
// When querying an object, don't include its children in the result
cib__set_call_options(command_options, crm_system_name,
cib_no_children);
}
if (sync_call || (acl_render_mode != pcmk__acl_render_none)) {
/* Wait for call to complete before returning.
*
* The ACL render modes work only with sync calls due to differences in
* output handling between sync/async. It shouldn't matter to the user
* whether the call is synchronous; for a CIB query, we have to wait for
* the result in order to display it in any case.
*/
cib__set_call_options(command_options, crm_system_name,
cib_sync_call);
}
if (admin_input_file != NULL) {
input = filename2xml(admin_input_file);
source = admin_input_file;
} else if (admin_input_xml != NULL) {
source = "input string";
input = string2xml(admin_input_xml);
} else if (admin_input_stdin) {
source = "STDIN";
input = stdin2xml();
} else if (acl_render_mode != pcmk__acl_render_none) {
- username = pcmk__uid2username(geteuid());
- if (pcmk_acl_required(username)) {
+ char *username = pcmk__uid2username(geteuid());
+ bool required = pcmk_acl_required(username);
+
+ free(username);
+
+ if (required) {
if (force) {
fprintf(stderr, "The supplied command can provide skewed"
" result since it is run under user that also"
" gets guarded per ACLs on their own right."
" Continuing since --force flag was"
" provided.\n");
} else {
+ exit_code = CRM_EX_UNSAFE;
fprintf(stderr, "The supplied command can provide skewed"
" result since it is run under user that also"
" gets guarded per ACLs in their own right."
" To accept the risk of such a possible"
" distortion (without even knowing it at this"
" time), use the --force flag.\n");
- crm_exit(CRM_EX_UNSAFE);
+ goto done;
}
-
}
- free(username);
- username = NULL;
if (cib_user == NULL) {
- fprintf(stderr, "The supplied command requires -U user specified.\n");
- crm_exit(CRM_EX_USAGE);
+ exit_code = CRM_EX_USAGE;
+ fprintf(stderr,
+ "The supplied command requires -U user specified.\n");
+ goto done;
}
/* we already stopped/warned ACL-controlled users about consequences */
acl_cred = cib_user;
cib_user = NULL;
}
if (input != NULL) {
crm_log_xml_debug(input, "[admin input]");
- } else if (source) {
+ } else if (source != NULL) {
+ exit_code = CRM_EX_CONFIG;
fprintf(stderr, "Couldn't parse input from %s.\n", source);
- crm_exit(CRM_EX_CONFIG);
+ goto done;
}
if (pcmk__str_eq(cib_action, "md5-sum", pcmk__str_casei)) {
char *digest = NULL;
if (input == NULL) {
+ exit_code = CRM_EX_USAGE;
fprintf(stderr, "Please supply XML to process with -X, -x or -p\n");
- crm_exit(CRM_EX_USAGE);
+ goto done;
}
digest = calculate_on_disk_digest(input);
fprintf(stderr, "Digest: ");
fprintf(stdout, "%s\n", pcmk__s(digest, "<null>"));
free(digest);
- free_xml(input);
- crm_exit(CRM_EX_OK);
+ goto done;
} else if (pcmk__str_eq(cib_action, "md5-sum-versioned", pcmk__str_casei)) {
char *digest = NULL;
const char *version = NULL;
if (input == NULL) {
+ exit_code = CRM_EX_USAGE;
fprintf(stderr, "Please supply XML to process with -X, -x or -p\n");
- crm_exit(CRM_EX_USAGE);
+ goto done;
}
version = crm_element_value(input, XML_ATTR_CRM_VERSION);
digest = calculate_xml_versioned_digest(input, FALSE, TRUE, version);
fprintf(stderr, "Versioned (%s) digest: ", version);
fprintf(stdout, "%s\n", pcmk__s(digest, "<null>"));
free(digest);
- free_xml(input);
- crm_exit(CRM_EX_OK);
+ goto done;
}
rc = do_init();
if (rc != pcmk_ok) {
- crm_err("Init failed, could not perform requested operations");
- fprintf(stderr, "Init failed, could not perform requested operations\n");
- free_xml(input);
- crm_exit(pcmk_rc2exitc(pcmk_legacy2rc(rc)));
+ rc = pcmk_legacy2rc(rc);
+ exit_code = pcmk_rc2exitc(rc);
+
+ crm_err("Init failed, could not perform requested operations: %s",
+ pcmk_rc_str(rc));
+ fprintf(stderr,
+ "Init failed, could not perform requested operations: %s\n",
+ pcmk_rc_str(rc));
+ goto done;
}
rc = do_work(input, command_options, &output);
if (rc > 0) {
/* wait for the reply by creating a mainloop and running it until
* the callbacks are invoked...
*/
request_id = rc;
the_cib->cmds->register_callback(the_cib, request_id,
message_timeout_sec, FALSE, NULL,
"cibadmin_op_callback",
cibadmin_op_callback);
mainloop = g_main_loop_new(NULL, FALSE);
crm_trace("%s waiting for reply from the local CIB", crm_system_name);
crm_info("Starting mainloop");
g_main_loop_run(mainloop);
} else if ((rc == -pcmk_err_schema_unchanged)
&& pcmk__str_eq(cib_action, PCMK__CIB_REQUEST_UPGRADE,
pcmk__str_none)) {
report_schema_unchanged();
} else if (rc < 0) {
rc = pcmk_legacy2rc(rc);
crm_err("Call failed: %s", pcmk_rc_str(rc));
fprintf(stderr, "Call failed: %s\n", pcmk_rc_str(rc));
if (rc == pcmk_rc_schema_validation) {
if (pcmk__str_eq(cib_action, PCMK__CIB_REQUEST_UPGRADE,
pcmk__str_none)) {
xmlNode *obj = NULL;
int version = 0;
if (the_cib->cmds->query(the_cib, NULL, &obj,
command_options) == pcmk_ok) {
update_validation(&obj, &version, 0, TRUE, FALSE);
}
} else if (output) {
validate_xml_verbose(output);
}
}
exit_code = pcmk_rc2exitc(rc);
}
if ((output != NULL) && (acl_render_mode != pcmk__acl_render_none)) {
xmlDoc *acl_evaled_doc;
rc = pcmk__acl_annotate_permissions(acl_cred, output->doc, &acl_evaled_doc);
if (rc == pcmk_rc_ok) {
xmlChar *rendered = NULL;
- free_xml(output);
- output = NULL;
rc = pcmk__acl_evaled_render(acl_evaled_doc, acl_render_mode,
&rendered);
if (rc != pcmk_rc_ok) {
+ exit_code = CRM_EX_CONFIG;
fprintf(stderr, "Could not render evaluated access: %s\n",
pcmk_rc_str(rc));
- crm_exit(CRM_EX_CONFIG);
+ goto done;
}
printf("%s\n", (char *) rendered);
free(rendered);
} else {
- fprintf(stderr, "Could not evaluate access per request (%s, error: %s)\n", acl_cred, pcmk_rc_str(rc));
- crm_exit(CRM_EX_CONFIG);
+ exit_code = CRM_EX_CONFIG;
+ fprintf(stderr,
+ "Could not evaluate access per request (%s, error: %s)\n",
+ acl_cred, pcmk_rc_str(rc));
+ goto done;
}
- }
- if (output != NULL) {
+ } else if (output != NULL) {
print_xml_output(output);
- free_xml(output);
}
crm_trace("%s exiting normally", crm_system_name);
+done:
+ free(host);
free_xml(input);
+ free_xml(output);
+
rc = cib__clean_up_connection(&the_cib);
if (exit_code == CRM_EX_OK) {
exit_code = pcmk_rc2exitc(rc);
}
- free(host);
crm_exit(exit_code);
}
int
do_work(xmlNode * input, int call_options, xmlNode ** output)
{
/* construct the request */
the_cib->call_timeout = message_timeout_sec;
if ((strcmp(cib_action, PCMK__CIB_REQUEST_REPLACE) == 0)
&& pcmk__str_eq(crm_element_name(input), XML_TAG_CIB, pcmk__str_casei)) {
xmlNode *status = pcmk_find_cib_element(input, XML_CIB_TAG_STATUS);
if (status == NULL) {
create_xml_node(input, XML_CIB_TAG_STATUS);
}
}
if (cib_action != NULL) {
crm_trace("Passing \"%s\" to variant_op...", cib_action);
return cib_internal_op(the_cib, cib_action, host, cib_section, input,
output, call_options, cib_user);
} else {
crm_err("You must specify an operation");
}
return -EINVAL;
}
int
do_init(void)
{
int rc = pcmk_ok;
the_cib = cib_new();
rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);
if (rc != pcmk_ok) {
crm_err("Could not connect to the CIB: %s", pcmk_strerror(rc));
fprintf(stderr, "Could not connect to the CIB: %s\n",
pcmk_strerror(rc));
}
return rc;
}
void
cibadmin_op_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
{
rc = pcmk_legacy2rc(rc);
exit_code = pcmk_rc2exitc(rc);
if (rc == pcmk_rc_schema_unchanged) {
report_schema_unchanged();
} else if (rc != pcmk_rc_ok) {
crm_warn("Call %s failed: %s " CRM_XS " rc=%d",
cib_action, pcmk_rc_str(rc), rc);
fprintf(stderr, "Call %s failed: %s\n", cib_action, pcmk_rc_str(rc));
print_xml_output(output);
} else if (pcmk__str_eq(cib_action, PCMK__CIB_REQUEST_QUERY, pcmk__str_none)
&& (output == NULL)) {
crm_err("Query returned no output");
crm_log_xml_err(msg, "no output");
} else if (output == NULL) {
crm_info("Call passed");
} else {
crm_info("Call passed");
print_xml_output(output);
}
if (call_id == request_id) {
g_main_loop_quit(mainloop);
} else {
crm_info("Message was not the response we were looking for (%d vs. %d)",
call_id, request_id);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Oct 29, 8:11 PM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
942567
Default Alt Text
(32 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment