root/tools/cibadmin.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_xml_output
  2. main
  3. do_work
  4. do_init
  5. cib_connection_destroy
  6. cibadmin_op_callback

   1 
   2 /*
   3  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
   4  *
   5  * This program is free software; you can redistribute it and/or
   6  * modify it under the terms of the GNU General Public
   7  * License as published by the Free Software Foundation; either
   8  * version 2 of the License, or (at your option) any later version.
   9  *
  10  * This software is distributed in the hope that it will be useful,
  11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13  * General Public License for more details.
  14  *
  15  * You should have received a copy of the GNU General Public
  16  * License along with this library; if not, write to the Free Software
  17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18  */
  19 
  20 #include <crm_internal.h>
  21 
  22 #include <sys/param.h>
  23 
  24 #include <crm/crm.h>
  25 
  26 #include <stdio.h>
  27 #include <sys/types.h>
  28 #include <unistd.h>
  29 
  30 #include <stdlib.h>
  31 #include <errno.h>
  32 #include <fcntl.h>
  33 
  34 #include <crm/msg_xml.h>
  35 #include <crm/common/xml.h>
  36 #include <crm/common/ipc.h>
  37 #include <crm/cib/internal.h>
  38 
  39 int exit_code = pcmk_ok;
  40 int message_timer_id = -1;
  41 int message_timeout_ms = 30;
  42 
  43 GMainLoop *mainloop = NULL;
  44 
  45 const char *host = NULL;
  46 void usage(const char *cmd, int exit_status);
  47 int do_init(void);
  48 int do_work(xmlNode * input, int command_options, xmlNode ** output);
  49 
  50 gboolean admin_message_timeout(gpointer data);
  51 void cib_connection_destroy(gpointer user_data);
  52 void cibadmin_op_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data);
  53 
  54 int command_options = 0;
  55 const char *cib_user = NULL;
  56 const char *cib_action = NULL;
  57 
  58 typedef struct str_list_s {
  59     int num_items;
  60     char *value;
  61     struct str_list_s *next;
  62 } str_list_t;
  63 
  64 const char *obj_type = NULL;
  65 char *status = NULL;
  66 char *migrate_from = NULL;
  67 char *migrate_res = NULL;
  68 char *subtype = NULL;
  69 char *reset = NULL;
  70 
  71 int request_id = 0;
  72 int operation_status = 0;
  73 cib_t *the_cib = NULL;
  74 gboolean force_flag = FALSE;
  75 gboolean quiet = FALSE;
  76 int bump_log_num = 0;
  77 
  78 /* *INDENT-OFF* */
  79 static struct crm_option long_options[] = {
  80     {"help",    0, 0, '?', "\tThis text"},
  81     {"version", 0, 0, '$', "\tVersion information"  },
  82     {"verbose", 0, 0, 'V', "\tIncrease debug output\n"},
  83 
  84     {"-spacer-",    0, 0, '-', "Commands:"},
  85     {"upgrade",     0, 0, 'u', "\tUpgrade the configuration to the latest syntax"},
  86     {"query",       0, 0, 'Q', "\tQuery the contents of the CIB"},
  87     {"erase",       0, 0, 'E', "\tErase the contents of the whole CIB"},
  88     {"bump",        0, 0, 'B', "\tIncrease the CIB's epoch value by 1"},
  89     {"create",      0, 0, 'C', "\tCreate an object in the CIB.  Will fail if the object already exists."},
  90     {"modify",      0, 0, 'M', "\tFind the object somewhere in the CIB's XML tree and update it.  Fails if the object does not exist unless -c is specified"},
  91     {"patch",       0, 0, 'P', "\tSupply an update in the form of an xml diff (See also: crm_diff)"},
  92     {"replace",     0, 0, 'R', "\tRecursively replace an object in the CIB"},
  93     {"delete",      0, 0, 'D', "\tDelete the first object matching the supplied criteria, Eg. <op id=\"rsc1_op1\" name=\"monitor\"/>"},
  94     {"-spacer-",    0, 0, '-', "\n\tThe tagname and all attributes must match in order for the element to be deleted\n"},
  95     {"delete-all",  0, 0, 'd', "When used with --xpath, remove all matching objects in the configuration instead of just the first one"},
  96     {"empty",       0, 0, 'a', "\tOutput an empty CIB"},
  97     {"md5-sum",     0, 0, '5', "\tCalculate the on-disk CIB digest"},
  98     {"md5-sum-versioned",  0, 0, '6', "Calculate an on-the-wire versioned CIB digest"},
  99     {"blank",       0, 0, '-', NULL, 1},
 100 
 101     {"-spacer-",1, 0, '-', "\nAdditional options:"},
 102     {"force",       0, 0, 'f'},
 103     {"timeout",     1, 0, 't', "Time (in seconds) to wait before declaring the operation failed"},
 104     {"user",        1, 0, 'U', "Run the command with permissions of the named user (valid only for the root and "CRM_DAEMON_USER" accounts)"},
 105     {"sync-call",   0, 0, 's', "Wait for call to complete before returning"},
 106     {"local",       0, 0, 'l', "\tCommand takes effect locally.  Should only be used for queries"},
 107     {"allow-create",0, 0, 'c', "(Advanced) Allow the target of a --modify,-M operation to be created if they do not exist"},
 108     {"no-children", 0, 0, 'n', "(Advanced) When querying an object, do not return include its children in the result\n"},
 109     {"no-bcast",    0, 0, 'b', NULL, 1},
 110 
 111     {"-spacer-",    0, 0, '-', "Data:"},
 112     {"xml-text",    1, 0, 'X', "Retrieve XML from the supplied string"},
 113     {"xml-file",    1, 0, 'x', "Retrieve XML from the named file"},
 114     {"xml-pipe",    0, 0, 'p', "Retrieve XML from stdin\n"},
 115 
 116     {"scope",       1, 0, 'o', "Limit the scope of the operation to a specific section of the CIB."},
 117     {"-spacer-",    0, 0, '-', "\tValid values are: nodes, resources, constraints, crm_config, rsc_defaults, op_defaults, status"},
 118 
 119     {"xpath",       1, 0, 'A', "A valid XPath to use instead of --scope,-o"},
 120     {"node-path",   0, 0, 'e',  "When performing XPath queries, return the address of any matches found."},
 121     {"-spacer-",    0, 0, '-', " Eg: /cib/configuration/resources/master[@id='ms_RH1_SCS']/primitive[@id='prm_RH1_SCS']", pcmk_option_paragraph},
 122     {"node",        1, 0, 'N', "(Advanced) Send command to the specified host\n"},
 123     {"-space-",     0, 0, '!', NULL, 1},
 124 
 125     {"-spacer-",    0, 0, '-', "\nExamples:\n"},
 126     {"-spacer-",    0, 0, '-', "Query the configuration from the local node:", pcmk_option_paragraph},
 127     {"-spacer-",    0, 0, '-', " cibadmin --query --local", pcmk_option_example},
 128 
 129     {"-spacer-",    0, 0, '-', "Query just the cluster options configuration:", pcmk_option_paragraph},
 130     {"-spacer-",    0, 0, '-', " cibadmin --query --scope crm_config", pcmk_option_example},
 131 
 132     {"-spacer-",    0, 0, '-', "Query all 'target-role' settings:", pcmk_option_paragraph},
 133     {"-spacer-",    0, 0, '-', " cibadmin --query --xpath \"//nvpair[@name='target-role']\"", pcmk_option_example},
 134 
 135     {"-spacer-",    0, 0, '-', "Remove all 'is-managed' settings:", pcmk_option_paragraph},
 136     {"-spacer-",    0, 0, '-', " cibadmin --delete-all --xpath \"//nvpair[@name='is-managed']\"", pcmk_option_example},
 137 
 138     {"-spacer-",    0, 0, '-', "Remove the resource named 'old':", pcmk_option_paragraph},
 139     {"-spacer-",    0, 0, '-', " cibadmin --delete --xml-text '<primitive id=\"old\"/>'", pcmk_option_example},
 140 
 141     {"-spacer-",    0, 0, '-', "Remove all resources from the configuration:", pcmk_option_paragraph},
 142     {"-spacer-",    0, 0, '-', " cibadmin --replace --scope resources --xml-text '<resources/>'", pcmk_option_example},
 143 
 144     {"-spacer-",    0, 0, '-', "Replace the complete configuration with the contents of $HOME/pacemaker.xml:", pcmk_option_paragraph},
 145     {"-spacer-",    0, 0, '-', " cibadmin --replace --xml-file $HOME/pacemaker.xml", pcmk_option_example},
 146 
 147     {"-spacer-",    0, 0, '-', "Replace the constraints section of the configuration with the contents of $HOME/constraints.xml:", pcmk_option_paragraph},
 148     {"-spacer-",    0, 0, '-', " cibadmin --replace --scope constraints --xml-file $HOME/constraints.xml", pcmk_option_example},
 149 
 150     {"-spacer-",    0, 0, '-', "Increase the configuration version to prevent old configurations from being loaded accidentally:", pcmk_option_paragraph},
 151     {"-spacer-",    0, 0, '-', " cibadmin --modify --xml-text '<cib admin_epoch=\"admin_epoch++\"/>'", pcmk_option_example},
 152 
 153     {"-spacer-",    0, 0, '-', "Edit the configuration with your favorite $EDITOR:", pcmk_option_paragraph},
 154     {"-spacer-",    0, 0, '-', " cibadmin --query > $HOME/local.xml", pcmk_option_example},
 155     {"-spacer-",    0, 0, '-', " $EDITOR $HOME/local.xml", pcmk_option_example},
 156     {"-spacer-",    0, 0, '-', " cibadmin --replace --xml-file $HOME/local.xml", pcmk_option_example},
 157 
 158     {"-spacer-",    0, 0, '-', "SEE ALSO:"},
 159     {"-spacer-",    0, 0, '-', " crm(8), pcs(8), crm_shadow(8), crm_diff(8)"},
 160 
 161     /* Legacy options */
 162     {"host",         1, 0, 'h', NULL, 1},
 163 
 164     {0, 0, 0, 0}
 165 };
 166 /* *INDENT-ON* */
 167 
 168 static void
 169 print_xml_output(xmlNode * xml)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171     char *buffer;
 172 
 173     if (!xml) {
 174         return;
 175     } else if (xml->type != XML_ELEMENT_NODE) {
 176         return;
 177     }
 178 
 179     if (command_options & cib_xpath_address) {
 180         const char *id = crm_element_value(xml, XML_ATTR_ID);
 181 
 182         if (safe_str_eq((const char *)xml->name, "xpath-query")) {
 183             xmlNode *child = NULL;
 184 
 185             for (child = xml->children; child; child = child->next) {
 186                 print_xml_output(child);
 187             }
 188 
 189         } else if (id) {
 190             printf("%s\n", id);
 191         }
 192 
 193     } else {
 194         buffer = dump_xml_formatted(xml);
 195         fprintf(stdout, "%s", crm_str(buffer));
 196         free(buffer);
 197     }
 198 }
 199 
 200 int
 201 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 202 {
 203     int argerr = 0;
 204     int flag;
 205     const char *source = NULL;
 206     const char *admin_input_xml = NULL;
 207     const char *admin_input_file = NULL;
 208     gboolean dangerous_cmd = FALSE;
 209     gboolean admin_input_stdin = FALSE;
 210     xmlNode *output = NULL;
 211     xmlNode *input = NULL;
 212 
 213     int option_index = 0;
 214 
 215     crm_xml_init(); /* Sets buffer allocation strategy */
 216     crm_log_cli_init("cibadmin");
 217     set_crm_log_level(LOG_CRIT);
 218     crm_set_options(NULL, "command [options] [data]", long_options,
 219                     "Provides direct access to the cluster configuration."
 220                     "\n\nAllows the configuration, or sections of it, to be queried, modified, replaced and deleted."
 221                     "\n\nWhere necessary, XML data will be obtained using the -X, -x, or -p options.\n");
 222 
 223     if (argc < 2) {
 224         crm_help('?', EX_USAGE);
 225     }
 226 
 227     while (1) {
 228         flag = crm_get_option(argc, argv, &option_index);
 229         if (flag == -1)
 230             break;
 231 
 232         switch (flag) {
 233             case 't':
 234                 message_timeout_ms = atoi(optarg);
 235                 if (message_timeout_ms < 1) {
 236                     message_timeout_ms = 30;
 237                 }
 238                 break;
 239             case 'A':
 240                 obj_type = optarg;
 241                 command_options |= cib_xpath;
 242                 break;
 243             case 'e':
 244                 command_options |= cib_xpath_address;
 245                 break;
 246             case 'u':
 247                 cib_action = CIB_OP_UPGRADE;
 248                 dangerous_cmd = TRUE;
 249                 break;
 250             case 'E':
 251                 cib_action = CIB_OP_ERASE;
 252                 dangerous_cmd = TRUE;
 253                 break;
 254             case 'Q':
 255                 cib_action = CIB_OP_QUERY;
 256                 quiet = TRUE;
 257                 break;
 258             case 'P':
 259                 cib_action = CIB_OP_APPLY_DIFF;
 260                 break;
 261             case 'U':
 262                 cib_user = optarg;
 263                 break;
 264             case 'M':
 265                 cib_action = CIB_OP_MODIFY;
 266                 break;
 267             case 'R':
 268                 cib_action = CIB_OP_REPLACE;
 269                 break;
 270             case 'C':
 271                 cib_action = CIB_OP_CREATE;
 272                 break;
 273             case 'D':
 274                 cib_action = CIB_OP_DELETE;
 275                 break;
 276             case '5':
 277                 cib_action = "md5-sum";
 278                 break;
 279             case '6':
 280                 cib_action = "md5-sum-versioned";
 281                 break;
 282             case 'c':
 283                 command_options |= cib_can_create;
 284                 break;
 285             case 'n':
 286                 command_options |= cib_no_children;
 287                 break;
 288             case 'B':
 289                 cib_action = CIB_OP_BUMP;
 290                 crm_log_args(argc, argv);
 291                 break;
 292             case 'V':
 293                 command_options = command_options | cib_verbose;
 294                 bump_log_num++;
 295                 break;
 296             case '?':
 297             case '$':
 298             case '!':
 299                 crm_help(flag, EX_OK);
 300                 break;
 301             case 'o':
 302                 crm_trace("Option %c => %s", flag, optarg);
 303                 obj_type = optarg;
 304                 break;
 305             case 'X':
 306                 crm_trace("Option %c => %s", flag, optarg);
 307                 admin_input_xml = optarg;
 308                 crm_log_args(argc, argv);
 309                 break;
 310             case 'x':
 311                 crm_trace("Option %c => %s", flag, optarg);
 312                 admin_input_file = optarg;
 313                 crm_log_args(argc, argv);
 314                 break;
 315             case 'p':
 316                 admin_input_stdin = TRUE;
 317                 crm_log_args(argc, argv);
 318                 break;
 319             case 'N':
 320             case 'h':
 321                 host = strdup(optarg);
 322                 break;
 323             case 'l':
 324                 command_options |= cib_scope_local;
 325                 break;
 326             case 'd':
 327                 cib_action = CIB_OP_DELETE;
 328                 command_options |= cib_multiple;
 329                 dangerous_cmd = TRUE;
 330                 break;
 331             case 'b':
 332                 dangerous_cmd = TRUE;
 333                 command_options |= cib_inhibit_bcast;
 334                 command_options |= cib_scope_local;
 335                 break;
 336             case 's':
 337                 command_options |= cib_sync_call;
 338                 break;
 339             case 'f':
 340                 force_flag = TRUE;
 341                 command_options |= cib_quorum_override;
 342                 crm_log_args(argc, argv);
 343                 break;
 344             case 'a':
 345                 output = createEmptyCib(1);
 346                 if (optind < argc) {
 347                     crm_xml_add(output, XML_ATTR_VALIDATION, argv[optind]);
 348                 }
 349                 admin_input_xml = dump_xml_formatted(output);
 350                 fprintf(stdout, "%s\n", crm_str(admin_input_xml));
 351                 goto bail;
 352                 break;
 353             default:
 354                 printf("Argument code 0%o (%c)" " is not (?yet?) supported\n", flag, flag);
 355                 ++argerr;
 356                 break;
 357         }
 358     }
 359 
 360     if (bump_log_num > 0) {
 361         quiet = FALSE;
 362     }
 363 
 364     while (bump_log_num > 0) {
 365         crm_bump_log_level(argc, argv);
 366         bump_log_num--;
 367     }
 368 
 369     if (optind < argc) {
 370         printf("non-option ARGV-elements: ");
 371         while (optind < argc)
 372             printf("%s ", argv[optind++]);
 373         printf("\n");
 374         crm_help('?', EX_USAGE);
 375     }
 376 
 377     if (optind > argc || cib_action == NULL) {
 378         ++argerr;
 379     }
 380 
 381     if (argerr) {
 382         crm_help('?', EX_USAGE);
 383     }
 384 
 385     if (dangerous_cmd && force_flag == FALSE) {
 386         fprintf(stderr, "The supplied command is considered dangerous."
 387                 "  To prevent accidental destruction of the cluster,"
 388                 " the --force flag is required in order to proceed.\n");
 389         fflush(stderr);
 390         exit_code = -EINVAL;
 391         goto bail;
 392     }
 393 
 394     if (admin_input_file != NULL) {
 395         input = filename2xml(admin_input_file);
 396         source = admin_input_file;
 397 
 398     } else if (admin_input_xml != NULL) {
 399         source = "input string";
 400         input = string2xml(admin_input_xml);
 401 
 402     } else if (admin_input_stdin) {
 403         source = "STDIN";
 404         input = stdin2xml();
 405     }
 406 
 407     if (input != NULL) {
 408         crm_log_xml_debug(input, "[admin input]");
 409 
 410     } else if (source) {
 411         fprintf(stderr, "Couldn't parse input from %s.\n", source);
 412         exit_code = -EINVAL;
 413         goto bail;
 414     }
 415 
 416     if (safe_str_eq(cib_action, "md5-sum")) {
 417         char *digest = NULL;
 418 
 419         if (input == NULL) {
 420             fprintf(stderr, "Please supply XML to process with -X, -x or -p\n");
 421             exit_code = -EINVAL;
 422             goto bail;
 423         }
 424 
 425         digest = calculate_on_disk_digest(input);
 426         fprintf(stderr, "Digest: ");
 427         fprintf(stdout, "%s\n", crm_str(digest));
 428         free(digest);
 429         goto bail;
 430 
 431     } else if (safe_str_eq(cib_action, "md5-sum-versioned")) {
 432         char *digest = NULL;
 433         const char *version = NULL;
 434 
 435         if (input == NULL) {
 436             fprintf(stderr, "Please supply XML to process with -X, -x or -p\n");
 437             exit_code = -EINVAL;
 438             goto bail;
 439         }
 440 
 441         version = crm_element_value(input, XML_ATTR_CRM_VERSION);
 442         digest = calculate_xml_versioned_digest(input, FALSE, TRUE, version);
 443         fprintf(stderr, "Versioned (%s) digest: ", version);
 444         fprintf(stdout, "%s\n", crm_str(digest));
 445         free(digest);
 446         goto bail;
 447     }
 448 
 449     exit_code = do_init();
 450     if (exit_code != pcmk_ok) {
 451         crm_err("Init failed, could not perform requested operations");
 452         fprintf(stderr, "Init failed, could not perform requested operations\n");
 453         return crm_exit(-exit_code);
 454     }
 455 
 456     exit_code = do_work(input, command_options, &output);
 457     if (exit_code > 0) {
 458         /* wait for the reply by creating a mainloop and running it until
 459          * the callbacks are invoked...
 460          */
 461         request_id = exit_code;
 462 
 463         the_cib->cmds->register_callback(the_cib, request_id, message_timeout_ms, FALSE, NULL,
 464                                          "cibadmin_op_callback", cibadmin_op_callback);
 465 
 466         mainloop = g_main_new(FALSE);
 467 
 468         crm_trace("%s waiting for reply from the local CIB", crm_system_name);
 469 
 470         crm_info("Starting mainloop");
 471         g_main_run(mainloop);
 472 
 473     } else if (exit_code < 0) {
 474         crm_err("Call failed: %s", pcmk_strerror(exit_code));
 475         fprintf(stderr, "Call failed: %s\n", pcmk_strerror(exit_code));
 476         operation_status = exit_code;
 477 
 478         if (exit_code == -pcmk_err_schema_validation) {
 479             if (crm_str_eq(cib_action, CIB_OP_UPGRADE, TRUE)) {
 480                 xmlNode *obj = NULL;
 481                 int version = 0, rc = 0;
 482 
 483                 rc = the_cib->cmds->query(the_cib, NULL, &obj, command_options);
 484                 if (rc == pcmk_ok) {
 485                     update_validation(&obj, &version, 0, TRUE, FALSE);
 486                 }
 487 
 488             } else if (output) {
 489                 validate_xml_verbose(output);
 490             }
 491         }
 492     }
 493 
 494     if (output != NULL) {
 495         print_xml_output(output);
 496         free_xml(output);
 497     }
 498 
 499     crm_trace("%s exiting normally", crm_system_name);
 500 
 501     free_xml(input);
 502     flag = the_cib->cmds->signoff(the_cib);
 503     cib_delete(the_cib);
 504 
 505     if(exit_code == pcmk_ok) {
 506         exit_code = flag;
 507     }
 508   bail:
 509     return crm_exit(exit_code);
 510 }
 511 
 512 int
 513 do_work(xmlNode * input, int call_options, xmlNode ** output)
     /* [previous][next][first][last][top][bottom][index][help] */
 514 {
 515     /* construct the request */
 516     the_cib->call_timeout = message_timeout_ms;
 517     if (strcasecmp(CIB_OP_REPLACE, cib_action) == 0
 518         && safe_str_eq(crm_element_name(input), XML_TAG_CIB)) {
 519         xmlNode *status = get_object_root(XML_CIB_TAG_STATUS, input);
 520 
 521         if (status == NULL) {
 522             create_xml_node(input, XML_CIB_TAG_STATUS);
 523         }
 524     }
 525 
 526     if (cib_action != NULL) {
 527         crm_trace("Passing \"%s\" to variant_op...", cib_action);
 528         return cib_internal_op(the_cib, cib_action, host, obj_type, input, output, call_options, cib_user);
 529 
 530     } else {
 531         crm_err("You must specify an operation");
 532     }
 533     return -EINVAL;
 534 }
 535 
 536 int
 537 do_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539     int rc = pcmk_ok;
 540 
 541     the_cib = cib_new();
 542     rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);
 543     if (rc != pcmk_ok) {
 544         crm_err("Signon to CIB failed: %s", pcmk_strerror(rc));
 545         fprintf(stderr, "Signon to CIB failed: %s\n", pcmk_strerror(rc));
 546     }
 547 
 548     return rc;
 549 }
 550 
 551 void
 552 cib_connection_destroy(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 553 {
 554     crm_err("Connection to the CIB terminated... exiting");
 555     g_main_quit(mainloop);
 556     return;
 557 }
 558 
 559 void
 560 cibadmin_op_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 561 {
 562     exit_code = rc;
 563 
 564     if (rc != 0) {
 565         crm_warn("Call %s failed (%d): %s", cib_action, rc, pcmk_strerror(rc));
 566         fprintf(stderr, "Call %s failed (%d): %s\n", cib_action, rc, pcmk_strerror(rc));
 567         print_xml_output(output);
 568 
 569     } else if (safe_str_eq(cib_action, CIB_OP_QUERY) && output == NULL) {
 570         crm_err("Output expected in query response");
 571         crm_log_xml_err(msg, "no output");
 572 
 573     } else if (output == NULL) {
 574         crm_info("Call passed");
 575 
 576     } else {
 577         crm_info("Call passed");
 578         print_xml_output(output);
 579     }
 580 
 581     if (call_id == request_id) {
 582         g_main_quit(mainloop);
 583 
 584     } else {
 585         crm_info("Message was not the response we were looking for (%d vs. %d", call_id,
 586                  request_id);
 587     }
 588 }

/* [previous][next][first][last][top][bottom][index][help] */