root/daemons/fenced/cts-fence-helper.c

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

DEFINITIONS

This source file includes following definitions.
  1. dispatch_helper
  2. st_callback
  3. st_global_callback
  4. passive_test
  5. run_fence_failure_test
  6. run_fence_failure_rollover_test
  7. run_standard_test
  8. sanity_tests
  9. standard_dev_test
  10. mainloop_callback
  11. register_callback_helper
  12. test_async_fence_pass
  13. test_async_fence_custom_timeout
  14. test_async_fence_timeout
  15. test_async_monitor
  16. test_register_async_devices
  17. try_mainloop_connect
  18. iterate_mainloop_tests
  19. trigger_iterate_mainloop_tests
  20. test_shutdown
  21. mainloop_tests
  22. main

   1 /*
   2  * Copyright 2009-2020 the Pacemaker project contributors
   3  *
   4  * This source code is licensed under the GNU General Public License version 2
   5  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   6  */
   7 
   8 #include <crm_internal.h>
   9 
  10 #include <sys/param.h>
  11 #include <stdio.h>
  12 #include <sys/time.h>
  13 #include <sys/types.h>
  14 #include <sys/stat.h>
  15 #include <unistd.h>
  16 #include <sys/utsname.h>
  17 
  18 #include <stdlib.h>
  19 #include <errno.h>
  20 #include <fcntl.h>
  21 
  22 #include <crm/crm.h>
  23 #include <crm/msg_xml.h>
  24 #include <crm/common/ipc.h>
  25 #include <crm/cluster/internal.h>
  26 
  27 #include <crm/stonith-ng.h>
  28 #include <crm/fencing/internal.h>
  29 #include <crm/common/xml.h>
  30 
  31 #include <crm/common/mainloop.h>
  32 
  33 static GMainLoop *mainloop = NULL;
  34 static crm_trigger_t *trig = NULL;
  35 static int mainloop_iter = 0;
  36 static int callback_rc = 0;
  37 typedef void (*mainloop_test_iteration_cb) (int check_event);
  38 
  39 #define MAINLOOP_DEFAULT_TIMEOUT 2
  40 
  41 #define mainloop_test_done(pass) \
  42     if (pass) { \
  43         crm_info("SUCCESS - %s", __func__); \
  44         mainloop_iter++;   \
  45         mainloop_set_trigger(trig);  \
  46     } else { \
  47         crm_err("FAILURE = %s async_callback %d", __func__, callback_rc); \
  48         crm_exit(CRM_EX_ERROR); \
  49     } \
  50     callback_rc = 0; \
  51 
  52 
  53 enum test_modes {
  54     test_standard = 0,  // test using a specific developer environment
  55     test_passive,       // watch notifications only
  56     test_api_sanity,    // sanity-test stonith client API using fence_dummy
  57     test_api_mainloop,  // sanity-test mainloop code with async responses
  58 };
  59 
  60 static pcmk__cli_option_t long_options[] = {
  61     // long option, argument type, storage, short option, description, flags
  62     {
  63         "verbose", no_argument, NULL, 'V',
  64         NULL, pcmk__option_default
  65     },
  66     {
  67         "version", no_argument, NULL, '$',
  68         NULL, pcmk__option_default
  69     },
  70     {
  71         "help", no_argument, NULL, '?',
  72         NULL, pcmk__option_default
  73     },
  74     {
  75         "passive", no_argument, NULL, 'p',
  76         NULL, pcmk__option_default
  77     },
  78     {
  79         "api_test", no_argument, NULL, 't',
  80         NULL, pcmk__option_default
  81     },
  82     {
  83         "mainloop_api_test", no_argument, NULL, 'm',
  84         NULL, pcmk__option_default
  85     },
  86     { 0, 0, 0, 0 }
  87 };
  88 
  89 static stonith_t *st = NULL;
  90 static struct pollfd pollfd;
  91 static const int st_opts = st_opt_sync_call;
  92 static int expected_notifications = 0;
  93 static int verbose = 0;
  94 
  95 static void
  96 dispatch_helper(int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98     int rc;
  99 
 100     crm_debug("Looking for notification");
 101     pollfd.events = POLLIN;
 102     while (true) {
 103         rc = poll(&pollfd, 1, timeout); /* wait 10 minutes, -1 forever */
 104         if (rc > 0) {
 105             if (!stonith_dispatch(st)) {
 106                 break;
 107             }
 108         } else {
 109             break;
 110         }
 111     }
 112 }
 113 
 114 static void
 115 st_callback(stonith_t * st, stonith_event_t * e)
     /* [previous][next][first][last][top][bottom][index][help] */
 116 {
 117     if (st->state == stonith_disconnected) {
 118         crm_exit(CRM_EX_DISCONNECT);
 119     }
 120 
 121     crm_notice("Operation %s requested by %s %s for peer %s.  %s reported: %s (ref=%s)",
 122                e->operation, e->origin, e->result == pcmk_ok ? "completed" : "failed",
 123                e->target, e->executioner ? e->executioner : "<none>",
 124                pcmk_strerror(e->result), e->id);
 125 
 126     if (expected_notifications) {
 127         expected_notifications--;
 128     }
 129 }
 130 
 131 static void
 132 st_global_callback(stonith_t * stonith, stonith_callback_data_t * data)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134     crm_notice("Call id %d completed with rc %d", data->call_id, data->rc);
 135 }
 136 
 137 static void
 138 passive_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 139 {
 140     int rc = 0;
 141 
 142     rc = st->cmds->connect(st, crm_system_name, &pollfd.fd);
 143     if (rc != pcmk_ok) {
 144         stonith_api_delete(st);
 145         crm_exit(CRM_EX_DISCONNECT);
 146     }
 147     st->cmds->register_notification(st, T_STONITH_NOTIFY_DISCONNECT, st_callback);
 148     st->cmds->register_notification(st, T_STONITH_NOTIFY_FENCE, st_callback);
 149     st->cmds->register_notification(st, STONITH_OP_DEVICE_ADD, st_callback);
 150     st->cmds->register_notification(st, STONITH_OP_DEVICE_DEL, st_callback);
 151     st->cmds->register_callback(st, 0, 120, st_opt_timeout_updates, NULL, "st_global_callback",
 152                                 st_global_callback);
 153 
 154     dispatch_helper(600 * 1000);
 155 }
 156 
 157 #define single_test(cmd, str, num_notifications, expected_rc) \
 158 { \
 159     int rc = 0; \
 160     rc = cmd; \
 161     expected_notifications = 0;  \
 162     if (num_notifications) { \
 163         expected_notifications = num_notifications; \
 164         dispatch_helper(500);  \
 165     } \
 166     if (rc != expected_rc) { \
 167         crm_err("FAILURE - expected rc %d != %d(%s) for cmd - %s", expected_rc, rc, pcmk_strerror(rc), str); \
 168         crm_exit(CRM_EX_ERROR); \
 169     } else if (expected_notifications) { \
 170         crm_err("FAILURE - expected %d notifications, got only %d for cmd - %s", \
 171             num_notifications, num_notifications - expected_notifications, str); \
 172         crm_exit(CRM_EX_ERROR); \
 173     } else { \
 174         if (verbose) {                   \
 175             crm_info("SUCCESS - %s: %d", str, rc);    \
 176         } else {   \
 177             crm_debug("SUCCESS - %s: %d", str, rc);    \
 178         }                          \
 179     } \
 180 }\
 181 
 182 static void
 183 run_fence_failure_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 184 {
 185     stonith_key_value_t *params = NULL;
 186 
 187     params = stonith_key_value_add(params, "pcmk_host_map", "false_1_node1=1,2 false_1_node2=3,4");
 188     params = stonith_key_value_add(params, "mode", "fail");
 189 
 190     single_test(st->
 191                 cmds->register_device(st, st_opts, "test-id1", "stonith-ng", "fence_dummy", params),
 192                 "Register device1 for failure test", 1, 0);
 193 
 194     single_test(st->cmds->fence(st, st_opts, "false_1_node2", "off", 3, 0),
 195                 "Fence failure results off", 1, -pcmk_err_generic);
 196 
 197     single_test(st->cmds->fence(st, st_opts, "false_1_node2", "reboot", 3, 0),
 198                 "Fence failure results reboot", 1, -pcmk_err_generic);
 199 
 200     single_test(st->cmds->remove_device(st, st_opts, "test-id1"),
 201                 "Remove device1 for failure test", 1, 0);
 202 
 203     stonith_key_value_freeall(params, 1, 1);
 204 }
 205 
 206 static void
 207 run_fence_failure_rollover_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209     stonith_key_value_t *params = NULL;
 210 
 211     params = stonith_key_value_add(params, "pcmk_host_map", "false_1_node1=1,2 false_1_node2=3,4");
 212     params = stonith_key_value_add(params, "mode", "fail");
 213 
 214     single_test(st->
 215                 cmds->register_device(st, st_opts, "test-id1", "stonith-ng", "fence_dummy", params),
 216                 "Register device1 for rollover test", 1, 0);
 217     stonith_key_value_freeall(params, 1, 1);
 218     params = NULL;
 219     params = stonith_key_value_add(params, "pcmk_host_map", "false_1_node1=1,2 false_1_node2=3,4");
 220     params = stonith_key_value_add(params, "mode", "pass");
 221 
 222     single_test(st->
 223                 cmds->register_device(st, st_opts, "test-id2", "stonith-ng", "fence_dummy", params),
 224                 "Register device2 for rollover test", 1, 0);
 225 
 226     single_test(st->cmds->fence(st, st_opts, "false_1_node2", "off", 3, 0),
 227                 "Fence rollover results off", 1, 0);
 228 
 229     /* Expect -ENODEV because fence_dummy requires 'on' to be executed on target */
 230     single_test(st->cmds->fence(st, st_opts, "false_1_node2", "on", 3, 0),
 231                 "Fence rollover results on", 1, -ENODEV);
 232 
 233     single_test(st->cmds->remove_device(st, st_opts, "test-id1"),
 234                 "Remove device1 for rollover tests", 1, 0);
 235 
 236     single_test(st->cmds->remove_device(st, st_opts, "test-id2"),
 237                 "Remove device2 for rollover tests", 1, 0);
 238 
 239     stonith_key_value_freeall(params, 1, 1);
 240 }
 241 
 242 static void
 243 run_standard_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245     stonith_key_value_t *params = NULL;
 246 
 247     params = stonith_key_value_add(params, "pcmk_host_map", "false_1_node1=1,2 false_1_node2=3,4");
 248     params = stonith_key_value_add(params, "mode", "pass");
 249     params = stonith_key_value_add(params, "mock_dynamic_hosts", "false_1_node1 false_1_node2");
 250 
 251     single_test(st->
 252                 cmds->register_device(st, st_opts, "test-id", "stonith-ng", "fence_dummy", params),
 253                 "Register", 1, 0);
 254     stonith_key_value_freeall(params, 1, 1);
 255     params = NULL;
 256 
 257     single_test(st->cmds->list(st, st_opts, "test-id", NULL, 1), "list", 1, 0);
 258 
 259     single_test(st->cmds->monitor(st, st_opts, "test-id", 1), "Monitor", 1, 0);
 260 
 261     single_test(st->cmds->status(st, st_opts, "test-id", "false_1_node2", 1),
 262                 "Status false_1_node2", 1, 0);
 263 
 264     single_test(st->cmds->status(st, st_opts, "test-id", "false_1_node1", 1),
 265                 "Status false_1_node1", 1, 0);
 266 
 267     single_test(st->cmds->fence(st, st_opts, "unknown-host", "off", 1, 0),
 268                 "Fence unknown-host (expected failure)", 0, -ENODEV);
 269 
 270     single_test(st->cmds->fence(st, st_opts, "false_1_node1", "off", 1, 0),
 271                 "Fence false_1_node1", 1, 0);
 272 
 273     /* Expect -ENODEV because fence_dummy requires 'on' to be executed on target */
 274     single_test(st->cmds->fence(st, st_opts, "false_1_node1", "on", 1, 0),
 275                 "Unfence false_1_node1", 1, -ENODEV);
 276 
 277     /* Confirm that an invalid level index is rejected */
 278     single_test(st->cmds->register_level(st, st_opts, "node1", 999, params),
 279                 "Attempt to register an invalid level index", 0, -EINVAL);
 280 
 281     single_test(st->cmds->remove_device(st, st_opts, "test-id"), "Remove test-id", 1, 0);
 282 
 283     stonith_key_value_freeall(params, 1, 1);
 284 }
 285 
 286 static void
 287 sanity_tests(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 288 {
 289     int rc = 0;
 290 
 291     rc = st->cmds->connect(st, crm_system_name, &pollfd.fd);
 292     if (rc != pcmk_ok) {
 293         stonith_api_delete(st);
 294         crm_exit(CRM_EX_DISCONNECT);
 295     }
 296     st->cmds->register_notification(st, T_STONITH_NOTIFY_DISCONNECT, st_callback);
 297     st->cmds->register_notification(st, T_STONITH_NOTIFY_FENCE, st_callback);
 298     st->cmds->register_notification(st, STONITH_OP_DEVICE_ADD, st_callback);
 299     st->cmds->register_notification(st, STONITH_OP_DEVICE_DEL, st_callback);
 300     st->cmds->register_callback(st, 0, 120, st_opt_timeout_updates, NULL, "st_global_callback",
 301                                 st_global_callback);
 302 
 303     crm_info("Starting API Sanity Tests");
 304     run_standard_test();
 305     run_fence_failure_test();
 306     run_fence_failure_rollover_test();
 307     crm_info("Sanity Tests Passed");
 308 }
 309 
 310 static void
 311 standard_dev_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313     int rc = 0;
 314     char *tmp = NULL;
 315     stonith_key_value_t *params = NULL;
 316 
 317     rc = st->cmds->connect(st, crm_system_name, &pollfd.fd);
 318     if (rc != pcmk_ok) {
 319         stonith_api_delete(st);
 320         crm_exit(CRM_EX_DISCONNECT);
 321     }
 322 
 323     params = stonith_key_value_add(params, "pcmk_host_map", "some-host=pcmk-7 true_1_node1=3,4");
 324 
 325     rc = st->cmds->register_device(st, st_opts, "test-id", "stonith-ng", "fence_xvm", params);
 326     crm_debug("Register: %d", rc);
 327 
 328     rc = st->cmds->list(st, st_opts, "test-id", &tmp, 10);
 329     crm_debug("List: %d output: %s", rc, tmp ? tmp : "<none>");
 330 
 331     rc = st->cmds->monitor(st, st_opts, "test-id", 10);
 332     crm_debug("Monitor: %d", rc);
 333 
 334     rc = st->cmds->status(st, st_opts, "test-id", "false_1_node2", 10);
 335     crm_debug("Status false_1_node2: %d", rc);
 336 
 337     rc = st->cmds->status(st, st_opts, "test-id", "false_1_node1", 10);
 338     crm_debug("Status false_1_node1: %d", rc);
 339 
 340     rc = st->cmds->fence(st, st_opts, "unknown-host", "off", 60, 0);
 341     crm_debug("Fence unknown-host: %d", rc);
 342 
 343     rc = st->cmds->status(st, st_opts, "test-id", "false_1_node1", 10);
 344     crm_debug("Status false_1_node1: %d", rc);
 345 
 346     rc = st->cmds->fence(st, st_opts, "false_1_node1", "off", 60, 0);
 347     crm_debug("Fence false_1_node1: %d", rc);
 348 
 349     rc = st->cmds->status(st, st_opts, "test-id", "false_1_node1", 10);
 350     crm_debug("Status false_1_node1: %d", rc);
 351 
 352     rc = st->cmds->fence(st, st_opts, "false_1_node1", "on", 10, 0);
 353     crm_debug("Unfence false_1_node1: %d", rc);
 354 
 355     rc = st->cmds->status(st, st_opts, "test-id", "false_1_node1", 10);
 356     crm_debug("Status false_1_node1: %d", rc);
 357 
 358     rc = st->cmds->fence(st, st_opts, "some-host", "off", 10, 0);
 359     crm_debug("Fence alias: %d", rc);
 360 
 361     rc = st->cmds->status(st, st_opts, "test-id", "some-host", 10);
 362     crm_debug("Status alias: %d", rc);
 363 
 364     rc = st->cmds->fence(st, st_opts, "false_1_node1", "on", 10, 0);
 365     crm_debug("Unfence false_1_node1: %d", rc);
 366 
 367     rc = st->cmds->remove_device(st, st_opts, "test-id");
 368     crm_debug("Remove test-id: %d", rc);
 369 
 370     stonith_key_value_freeall(params, 1, 1);
 371 }
 372 
 373 static void
 374  iterate_mainloop_tests(gboolean event_ready);
 375 
 376 static void
 377 mainloop_callback(stonith_t * stonith, stonith_callback_data_t * data)
     /* [previous][next][first][last][top][bottom][index][help] */
 378 {
 379     callback_rc = data->rc;
 380     iterate_mainloop_tests(TRUE);
 381 }
 382 
 383 static int
 384 register_callback_helper(int callid)
     /* [previous][next][first][last][top][bottom][index][help] */
 385 {
 386     return st->cmds->register_callback(st,
 387                                        callid,
 388                                        MAINLOOP_DEFAULT_TIMEOUT,
 389                                        st_opt_timeout_updates, NULL, "callback", mainloop_callback);
 390 }
 391 
 392 static void
 393 test_async_fence_pass(int check_event)
     /* [previous][next][first][last][top][bottom][index][help] */
 394 {
 395     int rc = 0;
 396 
 397     if (check_event) {
 398         if (callback_rc != 0) {
 399             mainloop_test_done(FALSE);
 400         } else {
 401             mainloop_test_done(TRUE);
 402         }
 403         return;
 404     }
 405 
 406     rc = st->cmds->fence(st, 0, "true_1_node1", "off", MAINLOOP_DEFAULT_TIMEOUT, 0);
 407     if (rc < 0) {
 408         crm_err("fence failed with rc %d", rc);
 409         mainloop_test_done(FALSE);
 410     }
 411     register_callback_helper(rc);
 412     /* wait for event */
 413 }
 414 
 415 #define CUSTOM_TIMEOUT_ADDITION 10
 416 static void
 417 test_async_fence_custom_timeout(int check_event)
     /* [previous][next][first][last][top][bottom][index][help] */
 418 {
 419     int rc = 0;
 420     static time_t begin = 0;
 421 
 422     if (check_event) {
 423         uint32_t diff = (time(NULL) - begin);
 424 
 425         if (callback_rc != -ETIME) {
 426             mainloop_test_done(FALSE);
 427         } else if (diff < CUSTOM_TIMEOUT_ADDITION + MAINLOOP_DEFAULT_TIMEOUT) {
 428             crm_err
 429                 ("Custom timeout test failed, callback expiration should be updated to %d, actual timeout was %d",
 430                  CUSTOM_TIMEOUT_ADDITION + MAINLOOP_DEFAULT_TIMEOUT, diff);
 431             mainloop_test_done(FALSE);
 432         } else {
 433             mainloop_test_done(TRUE);
 434         }
 435         return;
 436     }
 437     begin = time(NULL);
 438 
 439     rc = st->cmds->fence(st, 0, "custom_timeout_node1", "off", MAINLOOP_DEFAULT_TIMEOUT, 0);
 440     if (rc < 0) {
 441         crm_err("fence failed with rc %d", rc);
 442         mainloop_test_done(FALSE);
 443     }
 444     register_callback_helper(rc);
 445     /* wait for event */
 446 }
 447 
 448 static void
 449 test_async_fence_timeout(int check_event)
     /* [previous][next][first][last][top][bottom][index][help] */
 450 {
 451     int rc = 0;
 452 
 453     if (check_event) {
 454         if (callback_rc != -ENODEV) {
 455             mainloop_test_done(FALSE);
 456         } else {
 457             mainloop_test_done(TRUE);
 458         }
 459         return;
 460     }
 461 
 462     rc = st->cmds->fence(st, 0, "false_1_node2", "off", MAINLOOP_DEFAULT_TIMEOUT, 0);
 463     if (rc < 0) {
 464         crm_err("fence failed with rc %d", rc);
 465         mainloop_test_done(FALSE);
 466     }
 467     register_callback_helper(rc);
 468     /* wait for event */
 469 }
 470 
 471 static void
 472 test_async_monitor(int check_event)
     /* [previous][next][first][last][top][bottom][index][help] */
 473 {
 474     int rc = 0;
 475 
 476     if (check_event) {
 477         if (callback_rc) {
 478             mainloop_test_done(FALSE);
 479         } else {
 480             mainloop_test_done(TRUE);
 481         }
 482         return;
 483     }
 484 
 485     rc = st->cmds->monitor(st, 0, "false_1", MAINLOOP_DEFAULT_TIMEOUT);
 486     if (rc < 0) {
 487         crm_err("monitor failed with rc %d", rc);
 488         mainloop_test_done(FALSE);
 489     }
 490 
 491     register_callback_helper(rc);
 492     /* wait for event */
 493 }
 494 
 495 static void
 496 test_register_async_devices(int check_event)
     /* [previous][next][first][last][top][bottom][index][help] */
 497 {
 498     char buf[16] = { 0, };
 499     stonith_key_value_t *params = NULL;
 500 
 501     params = stonith_key_value_add(params, "pcmk_host_map", "false_1_node1=1,2");
 502     params = stonith_key_value_add(params, "mode", "fail");
 503     st->cmds->register_device(st, st_opts, "false_1", "stonith-ng", "fence_dummy", params);
 504     stonith_key_value_freeall(params, 1, 1);
 505 
 506     params = NULL;
 507     params = stonith_key_value_add(params, "pcmk_host_map", "true_1_node1=1,2");
 508     params = stonith_key_value_add(params, "mode", "pass");
 509     st->cmds->register_device(st, st_opts, "true_1", "stonith-ng", "fence_dummy", params);
 510     stonith_key_value_freeall(params, 1, 1);
 511 
 512     params = NULL;
 513     params = stonith_key_value_add(params, "pcmk_host_map", "custom_timeout_node1=1,2");
 514     params = stonith_key_value_add(params, "mode", "fail");
 515     params = stonith_key_value_add(params, "delay", "1000");
 516     snprintf(buf, sizeof(buf) - 1, "%d", MAINLOOP_DEFAULT_TIMEOUT + CUSTOM_TIMEOUT_ADDITION);
 517     params = stonith_key_value_add(params, "pcmk_off_timeout", buf);
 518     st->cmds->register_device(st, st_opts, "false_custom_timeout", "stonith-ng", "fence_dummy",
 519                               params);
 520     stonith_key_value_freeall(params, 1, 1);
 521 
 522     mainloop_test_done(TRUE);
 523 }
 524 
 525 static void
 526 try_mainloop_connect(int check_event)
     /* [previous][next][first][last][top][bottom][index][help] */
 527 {
 528     int rc = stonith_api_connect_retry(st, crm_system_name, 10);
 529 
 530     if (rc == pcmk_ok) {
 531         mainloop_test_done(TRUE);
 532         return;
 533     }
 534     crm_err("API CONNECTION FAILURE");
 535     mainloop_test_done(FALSE);
 536 }
 537 
 538 static void
 539 iterate_mainloop_tests(gboolean event_ready)
     /* [previous][next][first][last][top][bottom][index][help] */
 540 {
 541     static mainloop_test_iteration_cb callbacks[] = {
 542         try_mainloop_connect,
 543         test_register_async_devices,
 544         test_async_monitor,
 545         test_async_fence_pass,
 546         test_async_fence_timeout,
 547         test_async_fence_custom_timeout,
 548     };
 549 
 550     if (mainloop_iter == (sizeof(callbacks) / sizeof(mainloop_test_iteration_cb))) {
 551         /* all tests ran, everything passed */
 552         crm_info("ALL MAINLOOP TESTS PASSED!");
 553         crm_exit(CRM_EX_OK);
 554     }
 555 
 556     callbacks[mainloop_iter] (event_ready);
 557 }
 558 
 559 static gboolean
 560 trigger_iterate_mainloop_tests(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 561 {
 562     iterate_mainloop_tests(FALSE);
 563     return TRUE;
 564 }
 565 
 566 static void
 567 test_shutdown(int nsig)
     /* [previous][next][first][last][top][bottom][index][help] */
 568 {
 569     int rc = 0;
 570 
 571     if (st) {
 572         rc = st->cmds->disconnect(st);
 573         crm_info("Disconnect: %d", rc);
 574 
 575         crm_debug("Destroy");
 576         stonith_api_delete(st);
 577     }
 578 
 579     if (rc) {
 580         crm_exit(CRM_EX_ERROR);
 581     }
 582 }
 583 
 584 static void
 585 mainloop_tests(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 586 {
 587     trig = mainloop_add_trigger(G_PRIORITY_HIGH, trigger_iterate_mainloop_tests, NULL);
 588     mainloop_set_trigger(trig);
 589     mainloop_add_signal(SIGTERM, test_shutdown);
 590 
 591     crm_info("Starting");
 592     mainloop = g_main_loop_new(NULL, FALSE);
 593     g_main_loop_run(mainloop);
 594 }
 595 
 596 int
 597 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 598 {
 599     int argerr = 0;
 600     int flag;
 601     int option_index = 0;
 602 
 603     enum test_modes mode = test_standard;
 604 
 605     crm_log_cli_init("cts-fence-helper");
 606     pcmk__set_cli_options(NULL, "<mode> [options]", long_options,
 607                           "inject commands into the Pacemaker fencer, "
 608                           "and watch for events");
 609 
 610     while (1) {
 611         flag = pcmk__next_cli_option(argc, argv, &option_index, NULL);
 612         if (flag == -1) {
 613             break;
 614         }
 615 
 616         switch (flag) {
 617             case 'V':
 618                 verbose = 1;
 619                 break;
 620             case '$':
 621             case '?':
 622                 pcmk__cli_help(flag, CRM_EX_OK);
 623                 break;
 624             case 'p':
 625                 mode = test_passive;
 626                 break;
 627             case 't':
 628                 mode = test_api_sanity;
 629                 break;
 630             case 'm':
 631                 mode = test_api_mainloop;
 632                 break;
 633             default:
 634                 ++argerr;
 635                 break;
 636         }
 637     }
 638 
 639     crm_log_init(NULL, LOG_INFO, TRUE, (verbose? TRUE : FALSE), argc, argv,
 640                  FALSE);
 641 
 642     if (optind > argc) {
 643         ++argerr;
 644     }
 645 
 646     if (argerr) {
 647         pcmk__cli_help('?', CRM_EX_USAGE);
 648     }
 649 
 650     st = stonith_api_new();
 651     if (st == NULL) {
 652         crm_err("Could not connect to fencer: API memory allocation failed");
 653         crm_exit(CRM_EX_DISCONNECT);
 654     }
 655 
 656     switch (mode) {
 657         case test_standard:
 658             standard_dev_test();
 659             break;
 660         case test_passive:
 661             passive_test();
 662             break;
 663         case test_api_sanity:
 664             sanity_tests();
 665             break;
 666         case test_api_mainloop:
 667             mainloop_tests();
 668             break;
 669     }
 670 
 671     test_shutdown(0);
 672     return CRM_EX_OK;
 673 }

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