root/tools/crm_resource.c

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

DEFINITIONS

This source file includes following definitions.
  1. resource_ipc_timeout
  2. resource_ipc_connection_destroy
  3. start_mainloop
  4. resource_ipc_callback
  5. main

   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_resource.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 #include <libgen.h>
  34 #include <time.h>
  35 
  36 bool BE_QUIET = FALSE;
  37 bool scope_master = FALSE;
  38 int cib_options = cib_sync_call;
  39 
  40 GMainLoop *mainloop = NULL;
  41 
  42 #define message_timeout_ms 60*1000
  43 
  44 static gboolean
  45 resource_ipc_timeout(gpointer data)
     /* [previous][next][first][last][top][bottom][index][help] */
  46 {
  47     fprintf(stderr, "No messages received in %d seconds.. aborting\n",
  48             (int)message_timeout_ms / 1000);
  49     crm_err("No messages received in %d seconds", (int)message_timeout_ms / 1000);
  50     return crm_exit(-1);
  51 }
  52 
  53 static void
  54 resource_ipc_connection_destroy(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56     crm_info("Connection to CRMd was terminated");
  57     crm_exit(1);
  58 }
  59 
  60 static void
  61 start_mainloop(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63     if (crmd_replies_needed == 0) {
  64         return;
  65     }
  66 
  67     mainloop = g_main_new(FALSE);
  68     fprintf(stderr, "Waiting for %d replies from the CRMd", crmd_replies_needed);
  69     crm_debug("Waiting for %d replies from the CRMd", crmd_replies_needed);
  70 
  71     g_timeout_add(message_timeout_ms, resource_ipc_timeout, NULL);
  72     g_main_run(mainloop);
  73 }
  74 
  75 static int
  76 resource_ipc_callback(const char *buffer, ssize_t length, gpointer userdata)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78     xmlNode *msg = string2xml(buffer);
  79 
  80     fprintf(stderr, ".");
  81     crm_log_xml_trace(msg, "[inbound]");
  82 
  83     crmd_replies_needed--;
  84     if ((crmd_replies_needed == 0) && mainloop
  85         && g_main_loop_is_running(mainloop)) {
  86 
  87         fprintf(stderr, " OK\n");
  88         crm_debug("Got all the replies we expected");
  89         return crm_exit(pcmk_ok);
  90     }
  91 
  92     free_xml(msg);
  93     return 0;
  94 }
  95 
  96 struct ipc_client_callbacks crm_callbacks = {
  97     .dispatch = resource_ipc_callback,
  98     .destroy = resource_ipc_connection_destroy,
  99 };
 100 
 101 
 102 /* short option letters still available: eEJkKXyYZ */
 103 
 104 /* *INDENT-OFF* */
 105 static struct crm_option long_options[] = {
 106     /* Top-level Options */
 107     {
 108         "help", no_argument, NULL, '?',
 109         "\t\tDisplay this text and exit"
 110     },
 111     {
 112         "version", no_argument, NULL, '$',
 113         "\t\tDisplay version information and exit"
 114     },
 115     {
 116         "verbose", no_argument, NULL, 'V',
 117         "\t\tIncrease debug output (may be specified multiple times)"
 118     },
 119     {
 120         "quiet", no_argument, NULL, 'Q',
 121         "\t\tBe less descriptive in results"
 122     },
 123     {
 124         "resource", required_argument, NULL, 'r',
 125         "\tResource ID"
 126     },
 127 
 128     { "-spacer-", no_argument, NULL, '-', "\nQueries:" },
 129     {
 130         "list", no_argument, NULL, 'L',
 131         "\t\tList all cluster resources with status"},
 132     {
 133         "list-raw", no_argument, NULL, 'l',
 134         "\t\tList IDs of all instantiated resources (individual members rather than groups etc.)"
 135     },
 136     {
 137         "list-cts", no_argument, NULL, 'c',
 138         NULL, pcmk_option_hidden
 139     },
 140     {
 141         "list-operations", no_argument, NULL, 'O',
 142         "\tList active resource operations, optionally filtered by --resource and/or --node"
 143     },
 144     {
 145         "list-all-operations", no_argument, NULL, 'o',
 146         "List all resource operations, optionally filtered by --resource and/or --node"
 147     },
 148     {
 149         "pending", no_argument, NULL, 'j',
 150         "\t\tDisplay pending state if 'record-pending' is enabled",
 151         pcmk_option_hidden
 152     },
 153     {
 154         "list-standards", no_argument, NULL, 0,
 155         "\tList supported standards"
 156     },
 157     {
 158         "list-ocf-providers", no_argument, NULL, 0,
 159         "List all available OCF providers"
 160     },
 161     {
 162         "list-agents", required_argument, NULL, 0,
 163         "List all agents available for the named standard and/or provider."
 164     },
 165     {
 166         "list-ocf-alternatives", required_argument, NULL, 0,
 167         "List all available providers for the named OCF agent"
 168     },
 169     {
 170         "show-metadata", required_argument, NULL, 0,
 171         "Show the metadata for the named class:provider:agent"
 172     },
 173     {
 174         "query-xml", no_argument, NULL, 'q',
 175         "\tShow XML configuration of resource (after any template expansion)"
 176     },
 177     {
 178         "query-xml-raw", no_argument, NULL, 'w',
 179         "\tShow XML configuration of resource (before any template expansion)"
 180     },
 181     {
 182         "get-parameter", required_argument, NULL, 'g',
 183         "Display named parameter for resource.\n"
 184         "\t\t\t\tUse instance attribute unless --meta or --utilization is specified"
 185     },
 186     {
 187         "get-property", required_argument, NULL, 'G',
 188         "Display named property of resource ('class', 'type', or 'provider') (requires --resource)",
 189         pcmk_option_hidden
 190     },
 191     {
 192         "locate", no_argument, NULL, 'W',
 193         "\t\tShow node(s) currently running resource"
 194     },
 195     {
 196         "stack", no_argument, NULL, 'A',
 197         "\t\tDisplay the prerequisites and dependents of a resource"
 198     },
 199     {
 200         "constraints", no_argument, NULL, 'a',
 201         "\tDisplay the (co)location constraints that apply to a resource"
 202     },
 203     {
 204         "why", no_argument, NULL, 'Y',
 205         "\t\tShow why resources are not running, optionally filtered by --resource and/or --node"
 206     },
 207 
 208     { "-spacer-", no_argument, NULL, '-', "\nCommands:" },
 209     {
 210         "validate", no_argument, NULL, 0,
 211         "\t\tCall the validate-all action of the local given resource"
 212     },
 213     {
 214         "cleanup", no_argument, NULL, 'C',
 215 #if 0
 216         // new behavior disabled until 2.0.0
 217         "\t\tDelete failed operations from a resource's history allowing its current state to be rechecked.\n"
 218         "\t\t\t\tOptionally filtered by --resource, --node, --operation, and --interval (otherwise all).\n"
 219     },
 220     {
 221         "refresh", no_argument, NULL, 'R',
 222 #endif
 223         "\t\tDelete resource's history (including failures) so its current state is rechecked.\n"
 224         "\t\t\t\tOptionally filtered by --resource, --node, --operation, and --interval (otherwise all).\n"
 225         "\t\t\t\tUnless --force is specified, resource's group or clone (if any) will also be cleaned"
 226     },
 227     {
 228         "set-parameter", required_argument, NULL, 'p',
 229         "Set named parameter for resource (requires -v).\n"
 230         "\t\t\t\tUse instance attribute unless --meta or --utilization is specified."
 231     },
 232     {
 233         "delete-parameter", required_argument, NULL, 'd',
 234         "Delete named parameter for resource.\n"
 235         "\t\t\t\tUse instance attribute unless --meta or --utilization is specified."
 236     },
 237     {
 238         "set-property", required_argument, NULL, 'S',
 239         "Set named property of resource ('class', 'type', or 'provider') (requires -r, -t, -v)",
 240         pcmk_option_hidden
 241     },
 242 
 243     { "-spacer-", no_argument, NULL, '-', "\nResource location:" },
 244     {
 245         "move", no_argument, NULL, 'M',
 246         "\t\tCreate a constraint to move resource. If --node is specified, the constraint\n"
 247         "\t\t\t\twill be to move to that node, otherwise it will be to ban the current node.\n"
 248         "\t\t\t\tUnless --force is specified, this will return an error if the resource is\n"
 249         "\t\t\t\talready running on the specified node. If --force is specified, this will\n"
 250         "\t\t\t\talways ban the current node. Optional: --lifetime, --master.\n"
 251         "\t\t\t\tNOTE: This may prevent the resource from running on its previous location\n"
 252         "\t\t\t\tuntil the implicit constraint expires or is removed with --clear."
 253     },
 254     {
 255         "ban", no_argument, NULL, 'B',
 256         "\t\tCreate a constraint to keep resource off a node. Optional: --node, --lifetime, --master.\n"
 257         "\t\t\t\tNOTE: This will prevent the resource from running on the affected node\n"
 258         "\t\t\t\tuntil the implicit constraint expires or is removed with --clear.\n"
 259         "\t\t\t\tIf --node is not specified, it defaults to the node currently running the resource\n"
 260         "\t\t\t\tfor primitives and groups, or the master for master/slave clones with master-max=1\n"
 261         "\t\t\t\t(all other situations result in an error as there is no sane default).\n"
 262     },
 263     {
 264         "clear", no_argument, NULL, 'U',
 265         "\t\tRemove all constraints created by the --ban and/or --move commands.\n"
 266         "\t\t\t\tRequires: --resource. Optional: --node, --master.\n"
 267         "\t\t\t\tIf --node is not specified, all constraints created by --ban and --move\n"
 268         "\t\t\t\twill be removed for the named resource. If --node and --force are specified,\n"
 269         "\t\t\t\tany constraint created by --move will be cleared, even if it is not for the specified node."
 270     },
 271     {
 272         "lifetime", required_argument, NULL, 'u',
 273         "\tLifespan (as ISO 8601 duration) of created constraints (with -B, -M)\n"
 274         "\t\t\t\t(see https://en.wikipedia.org/wiki/ISO_8601#Durations)"
 275     },
 276     {
 277         "master", no_argument, NULL, 0,
 278         "\t\tLimit scope of command to the Master role (with -B, -M, -U).\n"
 279         "\t\t\t\tFor -B and -M, the previous master may remain active in the Slave role."
 280     },
 281 
 282     { "-spacer-", no_argument, NULL, '-', "\nAdvanced Commands:" },
 283     {
 284         "delete", no_argument, NULL, 'D',
 285         "\t\t(Advanced) Delete a resource from the CIB. Required: -t"
 286     },
 287     {
 288         "fail", no_argument, NULL, 'F',
 289         "\t\t(Advanced) Tell the cluster this resource has failed"
 290     },
 291     {
 292         "restart", no_argument, NULL, 0,
 293         "\t\t(Advanced) Tell the cluster to restart this resource and anything that depends on it"
 294     },
 295     {
 296         "wait", no_argument, NULL, 0,
 297         "\t\t(Advanced) Wait until the cluster settles into a stable state"
 298     },
 299     {
 300         "force-demote", no_argument, NULL, 0,
 301         "\t(Advanced) Bypass the cluster and demote a resource on the local node.\n"
 302         "\t\t\t\tUnless --force is specified, this will refuse to do so if the cluster\n"
 303         "\t\t\t\tbelieves the resource is a clone instance already running on the local node."
 304     },
 305     {
 306         "force-stop", no_argument, NULL, 0,
 307         "\t(Advanced) Bypass the cluster and stop a resource on the local node."
 308     },
 309     {
 310         "force-start", no_argument, NULL, 0,
 311         "\t(Advanced) Bypass the cluster and start a resource on the local node.\n"
 312         "\t\t\t\tUnless --force is specified, this will refuse to do so if the cluster\n"
 313         "\t\t\t\tbelieves the resource is a clone instance already running on the local node."
 314     },
 315     {
 316         "force-promote", no_argument, NULL, 0,
 317         "\t(Advanced) Bypass the cluster and promote a resource on the local node.\n"
 318         "\t\t\t\tUnless --force is specified, this will refuse to do so if the cluster\n"
 319         "\t\t\t\tbelieves the resource is a clone instance already running on the local node."
 320     },
 321     {
 322         "force-check", no_argument, NULL, 0,
 323         "\t(Advanced) Bypass the cluster and check the state of a resource on the local node."
 324     },
 325 
 326     { "-spacer-", no_argument, NULL, '-', "\nAdditional Options:" },
 327     {
 328         "node", required_argument, NULL, 'N',
 329         "\tNode name"
 330     },
 331     {
 332         "recursive", no_argument, NULL, 0,
 333         "\tFollow colocation chains when using --set-parameter"
 334     },
 335     {
 336         "resource-type", required_argument, NULL, 't',
 337         "Resource XML element (primitive, group, etc.) (with -D)"
 338     },
 339     {
 340         "parameter-value", required_argument, NULL, 'v',
 341         "Value to use with -p"
 342     },
 343     {
 344         "meta", no_argument, NULL, 'm',
 345         "\t\tUse resource meta-attribute instead of instance attribute (with -p, -g, -d)"
 346     },
 347     {
 348         "utilization", no_argument, NULL, 'z',
 349         "\tUse resource utilization attribute instead of instance attribute (with -p, -g, -d)"
 350     },
 351     {
 352         "operation", required_argument, NULL, 'n',
 353         "\tOperation to clear instead of all (with -C -r)"
 354     },
 355     {
 356         "interval", required_argument, NULL, 'I',
 357         "\tInterval of operation to clear (default 0) (with -C -r -n)"
 358     },
 359     {
 360         "set-name", required_argument, NULL, 's',
 361         "\t(Advanced) XML ID of attributes element to use (with -p, -d)"
 362     },
 363     {
 364         "nvpair", required_argument, NULL, 'i',
 365         "\t(Advanced) XML ID of nvpair element to use (with -p, -d)"
 366     },
 367     {
 368         "timeout", required_argument, NULL, 'T',
 369         "\t(Advanced) Abort if command does not finish in this time (with --restart, --wait, --force-*)"
 370     },
 371     {
 372         "force", no_argument, NULL, 'f',
 373         "\t\tIf making CIB changes, do so regardless of quorum.\n"
 374         "\t\t\t\tSee help for individual commands for additional behavior.\n"
 375     },
 376     {
 377         "xml-file", required_argument, NULL, 'x',
 378         NULL, pcmk_option_hidden
 379     },
 380 
 381     /* legacy options */
 382     {"host-uname", required_argument, NULL, 'H', NULL, pcmk_option_hidden},
 383     {"migrate", no_argument, NULL, 'M', NULL, pcmk_option_hidden},
 384     {"un-migrate", no_argument, NULL, 'U', NULL, pcmk_option_hidden},
 385     {"un-move", no_argument, NULL, 'U', NULL, pcmk_option_hidden},
 386 
 387     {"refresh",    0, 0, 'R', NULL, pcmk_option_hidden}, // remove this line for 2.0.0
 388     {"reprobe", no_argument, NULL, 'P', NULL, pcmk_option_hidden},
 389 
 390     {"-spacer-", 1, NULL, '-', "\nExamples:", pcmk_option_paragraph},
 391     {"-spacer-", 1, NULL, '-', "List the available OCF agents:", pcmk_option_paragraph},
 392     {"-spacer-", 1, NULL, '-', " crm_resource --list-agents ocf", pcmk_option_example},
 393     {"-spacer-", 1, NULL, '-', "List the available OCF agents from the linux-ha project:", pcmk_option_paragraph},
 394     {"-spacer-", 1, NULL, '-', " crm_resource --list-agents ocf:heartbeat", pcmk_option_example},
 395     {"-spacer-", 1, NULL, '-', "Move 'myResource' to a specific node:", pcmk_option_paragraph},
 396     {"-spacer-", 1, NULL, '-', " crm_resource --resource myResource --move --node altNode", pcmk_option_example},
 397     {"-spacer-", 1, NULL, '-', "Allow (but not force) 'myResource' to move back to its original location:", pcmk_option_paragraph},
 398     {"-spacer-", 1, NULL, '-', " crm_resource --resource myResource --clear", pcmk_option_example},
 399     {"-spacer-", 1, NULL, '-', "Stop 'myResource' (and anything that depends on it):", pcmk_option_paragraph},
 400     {"-spacer-", 1, NULL, '-', " crm_resource --resource myResource --set-parameter target-role --meta --parameter-value Stopped", pcmk_option_example},
 401     {"-spacer-", 1, NULL, '-', "Tell the cluster not to manage 'myResource':", pcmk_option_paragraph},
 402     {"-spacer-", 1, NULL, '-', "The cluster will not attempt to start or stop the resource under any circumstances."},
 403     {"-spacer-", 1, NULL, '-', "Useful when performing maintenance tasks on a resource.", pcmk_option_paragraph},
 404     {"-spacer-", 1, NULL, '-', " crm_resource --resource myResource --set-parameter is-managed --meta --parameter-value false", pcmk_option_example},
 405     {"-spacer-", 1, NULL, '-', "Erase the operation history of 'myResource' on 'aNode':", pcmk_option_paragraph},
 406     {"-spacer-", 1, NULL, '-', "The cluster will 'forget' the existing resource state (including any errors) and attempt to recover the resource."},
 407     {"-spacer-", 1, NULL, '-', "Useful when a resource had failed permanently and has been repaired by an administrator.", pcmk_option_paragraph},
 408     {"-spacer-", 1, NULL, '-', " crm_resource --resource myResource --cleanup --node aNode", pcmk_option_example},
 409 
 410     {0, 0, 0, 0}
 411 };
 412 /* *INDENT-ON* */
 413 
 414 
 415 int
 416 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 417 {
 418     char rsc_cmd = 'L';
 419 
 420     const char *rsc_id = NULL;
 421     const char *host_uname = NULL;
 422     const char *prop_name = NULL;
 423     const char *prop_value = NULL;
 424     const char *rsc_type = NULL;
 425     const char *prop_id = NULL;
 426     const char *prop_set = NULL;
 427     const char *rsc_long_cmd = NULL;
 428     const char *longname = NULL;
 429     const char *operation = NULL;
 430     const char *interval = NULL;
 431     const char *cib_file = getenv("CIB_file");
 432     GHashTable *override_params = NULL;
 433 
 434     char *xml_file = NULL;
 435     crm_ipc_t *crmd_channel = NULL;
 436     pe_working_set_t data_set = { 0, };
 437     cib_t *cib_conn = NULL;
 438     resource_t *rsc = NULL;
 439     bool recursive = FALSE;
 440     char *our_pid = NULL;
 441 
 442     bool require_resource = TRUE; /* whether command requires that resource be specified */
 443     bool require_dataset = TRUE;  /* whether command requires populated dataset instance */
 444     bool require_crmd = FALSE;    /* whether command requires connection to CRMd */
 445     bool just_errors = TRUE;      /* whether cleanup command deletes all history or just errors */
 446 
 447     int rc = pcmk_ok;
 448     int is_ocf_rc = 0;
 449     int option_index = 0;
 450     int timeout_ms = 0;
 451     int argerr = 0;
 452     int flag;
 453     int find_flags = 0;           // Flags to use when searching for resource
 454 
 455     crm_log_cli_init("crm_resource");
 456     crm_set_options(NULL, "(query|command) [options]", long_options,
 457                     "Perform tasks related to cluster resources.\nAllows resources to be queried (definition and location), modified, and moved around the cluster.\n");
 458 
 459     while (1) {
 460         flag = crm_get_option_long(argc, argv, &option_index, &longname);
 461         if (flag == -1)
 462             break;
 463 
 464         switch (flag) {
 465             case 0: /* long options with no short equivalent */
 466                 if (safe_str_eq("master", longname)) {
 467                     scope_master = TRUE;
 468 
 469                 } else if(safe_str_eq(longname, "recursive")) {
 470                     recursive = TRUE;
 471 
 472                 } else if (safe_str_eq("wait", longname)) {
 473                     rsc_cmd = flag;
 474                     rsc_long_cmd = longname;
 475                     require_resource = FALSE;
 476                     require_dataset = FALSE;
 477 
 478                 } else if (
 479                     safe_str_eq("validate", longname)
 480                     || safe_str_eq("restart", longname)
 481                     || safe_str_eq("force-demote",  longname)
 482                     || safe_str_eq("force-stop",    longname)
 483                     || safe_str_eq("force-start",   longname)
 484                     || safe_str_eq("force-promote", longname)
 485                     || safe_str_eq("force-check",   longname)) {
 486                     rsc_cmd = flag;
 487                     rsc_long_cmd = longname;
 488                     find_flags = pe_find_renamed|pe_find_anon;
 489                     crm_log_args(argc, argv);
 490 
 491                 } else if (safe_str_eq("list-ocf-providers", longname)
 492                            || safe_str_eq("list-ocf-alternatives", longname)
 493                            || safe_str_eq("list-standards", longname)) {
 494                     const char *text = NULL;
 495                     lrmd_list_t *list = NULL;
 496                     lrmd_list_t *iter = NULL;
 497                     lrmd_t *lrmd_conn = lrmd_api_new();
 498 
 499                     if (safe_str_eq("list-ocf-providers", longname)
 500                         || safe_str_eq("list-ocf-alternatives", longname)) {
 501                         rc = lrmd_conn->cmds->list_ocf_providers(lrmd_conn, optarg, &list);
 502                         text = "OCF providers";
 503 
 504                     } else if (safe_str_eq("list-standards", longname)) {
 505                         rc = lrmd_conn->cmds->list_standards(lrmd_conn, &list);
 506                         text = "standards";
 507                     }
 508 
 509                     if (rc > 0) {
 510                         rc = 0;
 511                         for (iter = list; iter != NULL; iter = iter->next) {
 512                             rc++;
 513                             printf("%s\n", iter->val);
 514                         }
 515                         lrmd_list_freeall(list);
 516 
 517                     } else if (optarg) {
 518                         fprintf(stderr, "No %s found for %s\n", text, optarg);
 519                     } else {
 520                         fprintf(stderr, "No %s found\n", text);
 521                     }
 522 
 523                     lrmd_api_delete(lrmd_conn);
 524                     return crm_exit(rc);
 525 
 526                 } else if (safe_str_eq("show-metadata", longname)) {
 527                     char *standard = NULL;
 528                     char *provider = NULL;
 529                     char *type = NULL;
 530                     char *metadata = NULL;
 531                     lrmd_t *lrmd_conn = lrmd_api_new();
 532 
 533                     rc = crm_parse_agent_spec(optarg, &standard, &provider, &type);
 534                     if (rc == pcmk_ok) {
 535                         rc = lrmd_conn->cmds->get_metadata(lrmd_conn, standard,
 536                                                            provider, type,
 537                                                            &metadata, 0);
 538                     } else {
 539                         fprintf(stderr,
 540                                 "'%s' is not a valid agent specification\n",
 541                                 optarg);
 542                     }
 543 
 544                     if (metadata) {
 545                         printf("%s\n", metadata);
 546                     } else {
 547                         fprintf(stderr, "Metadata query for %s failed: %s\n",
 548                                 optarg, pcmk_strerror(rc));
 549                     }
 550                     lrmd_api_delete(lrmd_conn);
 551                     return crm_exit(rc);
 552 
 553                 } else if (safe_str_eq("list-agents", longname)) {
 554                     lrmd_list_t *list = NULL;
 555                     lrmd_list_t *iter = NULL;
 556                     char *provider = strchr (optarg, ':');
 557                     lrmd_t *lrmd_conn = lrmd_api_new();
 558 
 559                     if (provider) {
 560                         *provider++ = 0;
 561                     }
 562                     rc = lrmd_conn->cmds->list_agents(lrmd_conn, &list, optarg, provider);
 563 
 564                     if (rc > 0) {
 565                         rc = 0;
 566                         for (iter = list; iter != NULL; iter = iter->next) {
 567                             printf("%s\n", iter->val);
 568                             rc++;
 569                         }
 570                         lrmd_list_freeall(list);
 571                         rc = 0;
 572                     } else {
 573                         fprintf(stderr, "No agents found for standard=%s, provider=%s\n",
 574                                 optarg, (provider? provider : "*"));
 575                         rc = -1;
 576                     }
 577                     lrmd_api_delete(lrmd_conn);
 578                     return crm_exit(rc);
 579 
 580                 } else {
 581                     crm_err("Unhandled long option: %s", longname);
 582                 }
 583                 break;
 584             case 'V':
 585                 resource_verbose++;
 586                 crm_bump_log_level(argc, argv);
 587                 break;
 588             case '$':
 589             case '?':
 590                 crm_help(flag, EX_OK);
 591                 break;
 592             case 'x':
 593                 xml_file = strdup(optarg);
 594                 break;
 595             case 'Q':
 596                 BE_QUIET = TRUE;
 597                 break;
 598             case 'm':
 599                 attr_set_type = XML_TAG_META_SETS;
 600                 break;
 601             case 'z':
 602                 attr_set_type = XML_TAG_UTILIZATION;
 603                 break;
 604             case 'u':
 605                 move_lifetime = strdup(optarg);
 606                 break;
 607             case 'f':
 608                 do_force = TRUE;
 609                 crm_log_args(argc, argv);
 610                 break;
 611             case 'i':
 612                 prop_id = optarg;
 613                 break;
 614             case 's':
 615                 prop_set = optarg;
 616                 break;
 617             case 'r':
 618                 rsc_id = optarg;
 619                 break;
 620             case 'v':
 621                 prop_value = optarg;
 622                 break;
 623             case 't':
 624                 rsc_type = optarg;
 625                 break;
 626             case 'T':
 627                 timeout_ms = crm_get_msec(optarg);
 628                 break;
 629 
 630             case 'R':
 631             case 'P':
 632                 crm_log_args(argc, argv);
 633                 require_resource = FALSE;
 634                 if (cib_file == NULL) {
 635                     require_crmd = TRUE;
 636                 }
 637                 just_errors = FALSE;
 638                 rsc_cmd = 'C';
 639                 find_flags = pe_find_renamed|pe_find_anon;
 640                 break;
 641 
 642             case 'C':
 643                 crm_log_args(argc, argv);
 644                 require_resource = FALSE;
 645                 if (cib_file == NULL) {
 646                     require_crmd = TRUE;
 647                 }
 648                 just_errors = FALSE; // disable until 2.0.0
 649                 rsc_cmd = 'C';
 650                 find_flags = pe_find_renamed|pe_find_anon;
 651                 break;
 652 
 653             case 'n':
 654                 operation = optarg;
 655                 break;
 656 
 657             case 'I':
 658                 interval = optarg;
 659                 break;
 660 
 661             case 'D':
 662                 require_dataset = FALSE;
 663                 crm_log_args(argc, argv);
 664                 rsc_cmd = flag;
 665                 find_flags = pe_find_renamed|pe_find_any;
 666                 break;
 667 
 668             case 'F':
 669                 require_crmd = TRUE;
 670                 crm_log_args(argc, argv);
 671                 rsc_cmd = flag;
 672                 break;
 673 
 674             case 'U':
 675             case 'B':
 676             case 'M':
 677                 crm_log_args(argc, argv);
 678                 rsc_cmd = flag;
 679                 find_flags = pe_find_renamed|pe_find_anon;
 680                 break;
 681 
 682             case 'c':
 683             case 'L':
 684             case 'l':
 685             case 'O':
 686             case 'o':
 687                 require_resource = FALSE;
 688                 rsc_cmd = flag;
 689                 break;
 690 
 691             case 'Y':
 692                 require_resource = FALSE;
 693                 rsc_cmd = flag;
 694                 find_flags = pe_find_renamed|pe_find_anon;
 695                 break;
 696 
 697             case 'q':
 698             case 'w':
 699                 rsc_cmd = flag;
 700                 find_flags = pe_find_renamed|pe_find_any;
 701                 break;
 702 
 703             case 'W':
 704             case 'A':
 705             case 'a':
 706                 rsc_cmd = flag;
 707                 find_flags = pe_find_renamed|pe_find_anon;
 708                 break;
 709 
 710             case 'j':
 711                 print_pending = TRUE;
 712                 break;
 713 
 714             case 'S':
 715                 require_dataset = FALSE;
 716                 crm_log_args(argc, argv);
 717                 prop_name = optarg;
 718                 rsc_cmd = flag;
 719                 find_flags = pe_find_renamed|pe_find_any;
 720                 break;
 721 
 722             case 'p':
 723             case 'd':
 724                 crm_log_args(argc, argv);
 725                 prop_name = optarg;
 726                 rsc_cmd = flag;
 727                 find_flags = pe_find_renamed|pe_find_any;
 728                 break;
 729 
 730             case 'G':
 731             case 'g':
 732                 prop_name = optarg;
 733                 rsc_cmd = flag;
 734                 find_flags = pe_find_renamed|pe_find_any;
 735                 break;
 736             case 'h':
 737             case 'H':
 738             case 'N':
 739                 crm_trace("Option %c => %s", flag, optarg);
 740                 host_uname = optarg;
 741                 break;
 742 
 743             default:
 744                 CMD_ERR("Argument code 0%o (%c) is not (?yet?) supported", flag, flag);
 745                 ++argerr;
 746                 break;
 747         }
 748     }
 749 
 750     // Catch the case where the user didn't specify a command
 751     if (rsc_cmd == 'L') {
 752         require_resource = FALSE;
 753     }
 754 
 755     if (optind < argc
 756         && argv[optind] != NULL
 757         && rsc_cmd == 0
 758         && rsc_long_cmd) {
 759 
 760         override_params = crm_str_table_new();
 761         while (optind < argc && argv[optind] != NULL) {
 762             char *name = calloc(1, strlen(argv[optind]));
 763             char *value = calloc(1, strlen(argv[optind]));
 764             int rc = sscanf(argv[optind], "%[^=]=%s", name, value);
 765 
 766             if(rc == 2) {
 767                 g_hash_table_replace(override_params, name, value);
 768 
 769             } else {
 770                 CMD_ERR("Error parsing '%s' as a name=value pair for --%s", argv[optind], rsc_long_cmd);
 771                 free(value);
 772                 free(name);
 773                 argerr++;
 774             }
 775             optind++;
 776         }
 777 
 778     } else if (optind < argc && argv[optind] != NULL && rsc_cmd == 0) {
 779         CMD_ERR("non-option ARGV-elements: ");
 780         while (optind < argc && argv[optind] != NULL) {
 781             CMD_ERR("[%d of %d] %s ", optind, argc, argv[optind]);
 782             optind++;
 783             argerr++;
 784         }
 785     }
 786 
 787     if (optind > argc) {
 788         ++argerr;
 789     }
 790 
 791     if (argerr) {
 792         CMD_ERR("Invalid option(s) supplied, use --help for valid usage");
 793         return crm_exit(EX_USAGE);
 794     }
 795 
 796     our_pid = crm_getpid_s();
 797 
 798     if (do_force) {
 799         crm_debug("Forcing...");
 800         cib_options |= cib_quorum_override;
 801     }
 802 
 803     data_set.input = NULL; /* make clean-up easier */
 804 
 805     if (require_resource && !rsc_id) {
 806         CMD_ERR("Must supply a resource id with -r");
 807         rc = -ENXIO;
 808         goto bail;
 809     }
 810 
 811     if (find_flags && rsc_id) {
 812         require_dataset = TRUE;
 813     }
 814 
 815     /* Establish a connection to the CIB */
 816     cib_conn = cib_new();
 817     rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command);
 818     if (rc != pcmk_ok) {
 819         CMD_ERR("Error signing on to the CIB service: %s", pcmk_strerror(rc));
 820         goto bail;
 821     }
 822 
 823     /* Populate working set from XML file if specified or CIB query otherwise */
 824     if (require_dataset) {
 825         xmlNode *cib_xml_copy = NULL;
 826 
 827         if (xml_file != NULL) {
 828             cib_xml_copy = filename2xml(xml_file);
 829 
 830         } else {
 831             rc = cib_conn->cmds->query(cib_conn, NULL, &cib_xml_copy, cib_scope_local | cib_sync_call);
 832         }
 833 
 834         if(rc != pcmk_ok) {
 835             goto bail;
 836         }
 837 
 838         /* Populate the working set instance */
 839         set_working_set_defaults(&data_set);
 840         rc = update_working_set_xml(&data_set, &cib_xml_copy);
 841         if (rc != pcmk_ok) {
 842             goto bail;
 843         }
 844         cluster_status(&data_set);
 845     }
 846 
 847     // If command requires that resource exist if specified, find it
 848     if (find_flags && rsc_id) {
 849         rsc = pe_find_resource_with_flags(data_set.resources, rsc_id,
 850                                           find_flags);
 851         if (rsc == NULL) {
 852             CMD_ERR("Resource '%s' not found", rsc_id);
 853             rc = -ENXIO;
 854             goto bail;
 855         }
 856     }
 857 
 858     /* Establish a connection to the CRMd if needed */
 859     if (require_crmd) {
 860         xmlNode *xml = NULL;
 861         mainloop_io_t *source =
 862             mainloop_add_ipc_client(CRM_SYSTEM_CRMD, G_PRIORITY_DEFAULT, 0, NULL, &crm_callbacks);
 863         crmd_channel = mainloop_get_ipc_client(source);
 864 
 865         if (crmd_channel == NULL) {
 866             CMD_ERR("Error signing on to the CRMd service");
 867             rc = -ENOTCONN;
 868             goto bail;
 869         }
 870 
 871         xml = create_hello_message(our_pid, crm_system_name, "0", "1");
 872         crm_ipc_send(crmd_channel, xml, 0, 0, NULL);
 873         free_xml(xml);
 874     }
 875 
 876     /* Handle rsc_cmd appropriately */
 877     if (rsc_cmd == 'L') {
 878         rc = pcmk_ok;
 879         cli_resource_print_list(&data_set, FALSE);
 880 
 881     } else if (rsc_cmd == 'l') {
 882         int found = 0;
 883         GListPtr lpc = NULL;
 884 
 885         rc = pcmk_ok;
 886         for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) {
 887             rsc = (resource_t *) lpc->data;
 888 
 889             found++;
 890             cli_resource_print_raw(rsc);
 891         }
 892 
 893         if (found == 0) {
 894             printf("NO resources configured\n");
 895             rc = -ENXIO;
 896         }
 897 
 898     } else if (rsc_cmd == 0 && rsc_long_cmd && safe_str_eq(rsc_long_cmd, "restart")) {
 899         rc = cli_resource_restart(rsc, host_uname, timeout_ms, cib_conn);
 900 
 901     } else if (rsc_cmd == 0 && rsc_long_cmd && safe_str_eq(rsc_long_cmd, "wait")) {
 902         rc = wait_till_stable(timeout_ms, cib_conn);
 903 
 904     } else if (rsc_cmd == 0 && rsc_long_cmd) {
 905         // validate, force-(stop|start|demote|promote|check)
 906         rc = cli_resource_execute(rsc, rsc_id, rsc_long_cmd, override_params,
 907                                   timeout_ms, cib_conn, &data_set);
 908         if (rc >= 0) {
 909             is_ocf_rc = 1;
 910         }
 911 
 912     } else if (rsc_cmd == 'A' || rsc_cmd == 'a') {
 913         GListPtr lpc = NULL;
 914         xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set.input);
 915 
 916         unpack_constraints(cib_constraints, &data_set);
 917 
 918         // Constraints apply to group/clone, not member/instance
 919         rsc = uber_parent(rsc);
 920 
 921         for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) {
 922             resource_t *r = (resource_t *) lpc->data;
 923 
 924             clear_bit(r->flags, pe_rsc_allocating);
 925         }
 926 
 927         cli_resource_print_colocation(rsc, TRUE, rsc_cmd == 'A', 1);
 928 
 929         fprintf(stdout, "* %s\n", rsc->id);
 930         cli_resource_print_location(rsc, NULL);
 931 
 932         for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) {
 933             resource_t *r = (resource_t *) lpc->data;
 934 
 935             clear_bit(r->flags, pe_rsc_allocating);
 936         }
 937 
 938         cli_resource_print_colocation(rsc, FALSE, rsc_cmd == 'A', 1);
 939 
 940     } else if (rsc_cmd == 'c') {
 941         GListPtr lpc = NULL;
 942 
 943         rc = pcmk_ok;
 944         for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) {
 945             rsc = (resource_t *) lpc->data;
 946             cli_resource_print_cts(rsc);
 947         }
 948         cli_resource_print_cts_constraints(&data_set);
 949 
 950     } else if (rsc_cmd == 'F') {
 951         rc = cli_resource_fail(crmd_channel, host_uname, rsc_id, &data_set);
 952         if (rc == pcmk_ok) {
 953             start_mainloop();
 954         }
 955 
 956     } else if (rsc_cmd == 'O') {
 957         rc = cli_resource_print_operations(rsc_id, host_uname, TRUE, &data_set);
 958 
 959     } else if (rsc_cmd == 'o') {
 960         rc = cli_resource_print_operations(rsc_id, host_uname, FALSE, &data_set);
 961 
 962     } else if (rsc_cmd == 'W') {
 963         rc = cli_resource_search(rsc, rsc_id, &data_set);
 964         if (rc >= 0) {
 965             rc = pcmk_ok;
 966         }
 967 
 968     } else if (rsc_cmd == 'q') {
 969         rc = cli_resource_print(rsc, &data_set, TRUE);
 970 
 971     } else if (rsc_cmd == 'w') {
 972         rc = cli_resource_print(rsc, &data_set, FALSE);
 973 
 974     } else if (rsc_cmd == 'Y') {
 975         node_t *dest = NULL;
 976 
 977         if (host_uname) {
 978             dest = pe_find_node(data_set.nodes, host_uname);
 979             if (dest == NULL) {
 980                 CMD_ERR("Unknown node: %s", host_uname);
 981                 rc = -ENXIO;
 982                 goto bail;
 983             }
 984         }
 985         cli_resource_why(cib_conn, data_set.resources, rsc, dest);
 986         rc = pcmk_ok;
 987 
 988     } else if (rsc_cmd == 'U') {
 989         node_t *dest = NULL;
 990 
 991         if (host_uname) {
 992             dest = pe_find_node(data_set.nodes, host_uname);
 993             if (dest == NULL) {
 994                 CMD_ERR("Unknown node: %s", host_uname);
 995                 rc = -ENXIO;
 996                 goto bail;
 997             }
 998             rc = cli_resource_clear(rsc_id, dest->details->uname, NULL, cib_conn);
 999 
1000         } else {
1001             rc = cli_resource_clear(rsc_id, NULL, data_set.nodes, cib_conn);
1002         }
1003 
1004     } else if (rsc_cmd == 'M' && host_uname) {
1005         rc = cli_resource_move(rsc, rsc_id, host_uname, cib_conn, &data_set);
1006 
1007     } else if (rsc_cmd == 'B' && host_uname) {
1008         node_t *dest = pe_find_node(data_set.nodes, host_uname);
1009 
1010         if (dest == NULL) {
1011             CMD_ERR("Error performing operation: node '%s' is unknown", host_uname);
1012             rc = -ENXIO;
1013             goto bail;
1014         }
1015         rc = cli_resource_ban(rsc_id, dest->details->uname, NULL, cib_conn);
1016 
1017     } else if (rsc_cmd == 'B' || rsc_cmd == 'M') {
1018         rc = -EINVAL;
1019         if (g_list_length(rsc->running_on) == 1) {
1020             node_t *current = rsc->running_on->data;
1021             rc = cli_resource_ban(rsc_id, current->details->uname, NULL, cib_conn);
1022 
1023         } else if(rsc->variant == pe_master) {
1024             int count = 0;
1025             GListPtr iter = NULL;
1026             node_t *current = NULL;
1027 
1028             for(iter = rsc->children; iter; iter = iter->next) {
1029                 resource_t *child = (resource_t *)iter->data;
1030                 enum rsc_role_e child_role = child->fns->state(child, TRUE);
1031 
1032                 if(child_role == RSC_ROLE_MASTER) {
1033                     count++;
1034                     current = child->running_on->data;
1035                 }
1036             }
1037 
1038             if(count == 1 && current) {
1039                 rc = cli_resource_ban(rsc_id, current->details->uname, NULL, cib_conn);
1040 
1041             } else {
1042                 CMD_ERR("Resource '%s' not moved: active in %d locations (promoted in %d).", rsc_id, g_list_length(rsc->running_on), count);
1043                 CMD_ERR("You can prevent '%s' from running on a specific location with: --ban --node <name>", rsc_id);
1044                 CMD_ERR("You can prevent '%s' from being promoted at a specific location with:"
1045                         " --ban --master --node <name>", rsc_id);
1046             }
1047 
1048         } else {
1049             CMD_ERR("Resource '%s' not moved: active in %d locations.", rsc_id, g_list_length(rsc->running_on));
1050             CMD_ERR("You can prevent '%s' from running on a specific location with: --ban --node <name>", rsc_id);
1051         }
1052 
1053     } else if (rsc_cmd == 'G') {
1054         rc = cli_resource_print_property(rsc, prop_name, &data_set);
1055 
1056     } else if (rsc_cmd == 'S') {
1057         xmlNode *msg_data = NULL;
1058 
1059         if ((rsc_type == NULL) || !strlen(rsc_type)) {
1060             CMD_ERR("Must specify -t with resource type");
1061             rc = -ENXIO;
1062             goto bail;
1063 
1064         } else if ((prop_value == NULL) || !strlen(prop_value)) {
1065             CMD_ERR("Must supply -v with new value");
1066             rc = -EINVAL;
1067             goto bail;
1068         }
1069 
1070         CRM_LOG_ASSERT(prop_name != NULL);
1071 
1072         msg_data = create_xml_node(NULL, rsc_type);
1073         crm_xml_add(msg_data, XML_ATTR_ID, rsc_id);
1074         crm_xml_add(msg_data, prop_name, prop_value);
1075 
1076         rc = cib_conn->cmds->modify(cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options);
1077         free_xml(msg_data);
1078 
1079     } else if (rsc_cmd == 'g') {
1080         rc = cli_resource_print_attribute(rsc, prop_name, &data_set);
1081 
1082     } else if (rsc_cmd == 'p') {
1083         if (prop_value == NULL || strlen(prop_value) == 0) {
1084             CMD_ERR("You need to supply a value with the -v option");
1085             rc = -EINVAL;
1086             goto bail;
1087         }
1088 
1089         /* coverity[var_deref_model] False positive */
1090         rc = cli_resource_update_attribute(rsc, rsc_id, prop_set, prop_id,
1091                                            prop_name, prop_value, recursive,
1092                                            cib_conn, &data_set);
1093 
1094     } else if (rsc_cmd == 'd') {
1095         /* coverity[var_deref_model] False positive */
1096         rc = cli_resource_delete_attribute(rsc, rsc_id, prop_set, prop_id,
1097                                            prop_name, cib_conn, &data_set);
1098 
1099     } else if (rsc_cmd == 'C' && just_errors) {
1100         crmd_replies_needed = 0;
1101         for (xmlNode *xml_op = __xml_first_child(data_set.failed); xml_op != NULL;
1102              xml_op = __xml_next(xml_op)) {
1103 
1104             const char *node = crm_element_value(xml_op, XML_ATTR_UNAME);
1105             const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
1106             const char *task_interval = crm_element_value(xml_op, XML_LRM_ATTR_INTERVAL);
1107             const char *resource_name = crm_element_value(xml_op, XML_LRM_ATTR_RSCID);
1108 
1109             if(resource_name == NULL) {
1110                 continue;
1111             } else if(host_uname && safe_str_neq(host_uname, node)) {
1112                 continue;
1113             } else if(rsc_id && safe_str_neq(rsc_id, resource_name)) {
1114                 continue;
1115             } else if(operation && safe_str_neq(operation, task)) {
1116                 continue;
1117             } else if(interval && safe_str_neq(interval, task_interval)) {
1118                 continue;
1119             }
1120 
1121             crm_debug("Erasing %s failure for %s (%s detected) on %s",
1122                       task, rsc->id, resource_name, node);
1123             rc = cli_resource_delete(crmd_channel, node, rsc, task,
1124                                      task_interval, &data_set);
1125         }
1126 
1127         if(rsc && (rc == pcmk_ok) && (BE_QUIET == FALSE)) {
1128             /* Now check XML_RSC_ATTR_TARGET_ROLE and XML_RSC_ATTR_MANAGED */
1129             cli_resource_check(cib_conn, rsc);
1130         }
1131 
1132         if (rc == pcmk_ok) {
1133             start_mainloop();
1134         }
1135 
1136     } else if ((rsc_cmd == 'C') && rsc) {
1137         if(do_force == FALSE) {
1138             rsc = uber_parent(rsc);
1139         }
1140 
1141         crm_debug("Re-checking the state of %s (%s requested) on %s",
1142                   rsc->id, rsc_id, host_uname);
1143         crmd_replies_needed = 0;
1144         rc = cli_resource_delete(crmd_channel, host_uname, rsc, operation,
1145                                  interval, &data_set);
1146 
1147         if(rc == pcmk_ok && BE_QUIET == FALSE) {
1148             /* Now check XML_RSC_ATTR_TARGET_ROLE and XML_RSC_ATTR_MANAGED */
1149             cli_resource_check(cib_conn, rsc);
1150         }
1151 
1152         if (rc == pcmk_ok) {
1153             start_mainloop();
1154         }
1155 
1156     } else if (rsc_cmd == 'C') {
1157 #if HAVE_ATOMIC_ATTRD
1158         const char *router_node = host_uname;
1159         xmlNode *msg_data = NULL;
1160         xmlNode *cmd = NULL;
1161         int attr_options = attrd_opt_none;
1162 
1163         if (host_uname) {
1164             node_t *node = pe_find_node(data_set.nodes, host_uname);
1165 
1166             if (node && is_remote_node(node)) {
1167                 if (node->details->remote_rsc == NULL || node->details->remote_rsc->running_on == NULL) {
1168                     CMD_ERR("No lrmd connection detected to remote node %s", host_uname);
1169                     rc = -ENXIO;
1170                     goto bail;
1171                 }
1172                 node = node->details->remote_rsc->running_on->data;
1173                 router_node = node->details->uname;
1174                 attr_options |= attrd_opt_remote;
1175             }
1176         }
1177 
1178         if (crmd_channel == NULL) {
1179             printf("Dry run: skipping clean-up of %s due to CIB_file\n",
1180                    host_uname? host_uname : "all nodes");
1181             rc = pcmk_ok;
1182             goto bail;
1183         }
1184 
1185         msg_data = create_xml_node(NULL, "crm-resource-reprobe-op");
1186         crm_xml_add(msg_data, XML_LRM_ATTR_TARGET, host_uname);
1187         if (safe_str_neq(router_node, host_uname)) {
1188             crm_xml_add(msg_data, XML_LRM_ATTR_ROUTER_NODE, router_node);
1189         }
1190 
1191         cmd = create_request(CRM_OP_REPROBE, msg_data, router_node,
1192                              CRM_SYSTEM_CRMD, crm_system_name, our_pid);
1193         free_xml(msg_data);
1194 
1195         crm_debug("Re-checking the state of all resources on %s", host_uname?host_uname:"all nodes");
1196 
1197         rc = attrd_clear_delegate(NULL, host_uname, NULL, NULL, NULL, NULL,
1198                                   attr_options);
1199 
1200         if (crm_ipc_send(crmd_channel, cmd, 0, 0, NULL) > 0) {
1201             start_mainloop();
1202         }
1203 
1204         free_xml(cmd);
1205 #else
1206         GListPtr rIter = NULL;
1207 
1208         crmd_replies_needed = 0;
1209         for (rIter = data_set.resources; rIter; rIter = rIter->next) {
1210             rsc = rIter->data;
1211             cli_resource_delete(crmd_channel, host_uname, rsc, NULL, NULL,
1212                                 &data_set);
1213         }
1214 
1215         start_mainloop();
1216 #endif
1217 
1218     } else if (rsc_cmd == 'D') {
1219         xmlNode *msg_data = NULL;
1220 
1221         if (rsc_type == NULL) {
1222             CMD_ERR("You need to specify a resource type with -t");
1223             rc = -ENXIO;
1224             goto bail;
1225         }
1226 
1227         msg_data = create_xml_node(NULL, rsc_type);
1228         crm_xml_add(msg_data, XML_ATTR_ID, rsc_id);
1229 
1230         rc = cib_conn->cmds->delete(cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options);
1231         free_xml(msg_data);
1232 
1233     } else {
1234         CMD_ERR("Unknown command: %c", rsc_cmd);
1235     }
1236 
1237   bail:
1238 
1239     free(our_pid);
1240 
1241     if (data_set.input != NULL) {
1242         cleanup_alloc_calculations(&data_set);
1243     }
1244     if (cib_conn != NULL) {
1245         cib_conn->cmds->signoff(cib_conn);
1246         cib_delete(cib_conn);
1247     }
1248 
1249     if (rc == -pcmk_err_no_quorum) {
1250         CMD_ERR("Error performing operation: %s", pcmk_strerror(rc));
1251         CMD_ERR("Try using -f");
1252 
1253     } else if (rc != pcmk_ok && !is_ocf_rc) {
1254         CMD_ERR("Error performing operation: %s", pcmk_strerror(rc));
1255     }
1256 
1257     return crm_exit(rc);
1258 }

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