LCOV - code coverage report
Current view: top level - pacemaker - pcmk_fence.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 0 215 0.0 %
Date: 2024-05-07 11:09:47 Functions: 0 16 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2009-2024 the Pacemaker project contributors
       3             :  *
       4             :  * The version control history for this file may have further details.
       5             :  *
       6             :  * This source code is licensed under the GNU General Public License version 2
       7             :  * or later (GPLv2+) WITHOUT ANY WARRANTY.
       8             :  */
       9             : 
      10             : #include <crm_internal.h>
      11             : #include <crm/common/mainloop.h>
      12             : #include <crm/common/results.h>
      13             : #include <crm/common/output.h>
      14             : #include <crm/common/output_internal.h>
      15             : #include <crm/stonith-ng.h>
      16             : #include <crm/fencing/internal.h>   // stonith__*
      17             : 
      18             : #include <glib.h>
      19             : #include <libxml/tree.h>
      20             : #include <pacemaker.h>
      21             : #include <pacemaker-internal.h>
      22             : 
      23             : static const int st_opts = st_opt_sync_call | st_opt_allow_suicide;
      24             : 
      25             : static GMainLoop *mainloop = NULL;
      26             : 
      27             : static struct {
      28             :     stonith_t *st;
      29             :     const char *target;
      30             :     const char *action;
      31             :     char *name;
      32             :     unsigned int timeout;
      33             :     unsigned int tolerance;
      34             :     int delay;
      35             :     pcmk__action_result_t result;
      36             : } async_fence_data = { NULL, };
      37             : 
      38             : static int
      39           0 : handle_level(stonith_t *st, const char *target, int fence_level,
      40             :              const stonith_key_value_t *devices, bool added)
      41             : {
      42           0 :     const char *node = NULL;
      43           0 :     const char *pattern = NULL;
      44           0 :     const char *name = NULL;
      45           0 :     char *value = NULL;
      46           0 :     int rc = pcmk_rc_ok;
      47             : 
      48           0 :     if (target == NULL) {
      49             :         // Not really possible, but makes static analysis happy
      50           0 :         return EINVAL;
      51             :     }
      52             : 
      53             :     /* Determine if targeting by attribute, node name pattern or node name */
      54           0 :     value = strchr(target, '=');
      55           0 :     if (value != NULL)  {
      56           0 :         name = target;
      57           0 :         *value++ = '\0';
      58           0 :     } else if (*target == '@') {
      59           0 :         pattern = target + 1;
      60             :     } else {
      61           0 :         node = target;
      62             :     }
      63             : 
      64             :     /* Register or unregister level as appropriate */
      65           0 :     if (added) {
      66           0 :         rc = st->cmds->register_level_full(st, st_opts, node, pattern,
      67             :                                            name, value, fence_level,
      68             :                                            devices);
      69             :     } else {
      70           0 :         rc = st->cmds->remove_level_full(st, st_opts, node, pattern,
      71             :                                          name, value, fence_level);
      72             :     }
      73             : 
      74           0 :     return pcmk_legacy2rc(rc);
      75             : }
      76             : 
      77             : static stonith_history_t *
      78           0 : reduce_fence_history(stonith_history_t *history)
      79             : {
      80             :     stonith_history_t *new, *hp, *np;
      81             : 
      82           0 :     if (!history) {
      83           0 :         return history;
      84             :     }
      85             : 
      86           0 :     new = history;
      87           0 :     hp = new->next;
      88           0 :     new->next = NULL;
      89             : 
      90           0 :     while (hp) {
      91           0 :         stonith_history_t *hp_next = hp->next;
      92             : 
      93           0 :         hp->next = NULL;
      94             : 
      95           0 :         for (np = new; ; np = np->next) {
      96           0 :             if ((hp->state == st_done) || (hp->state == st_failed)) {
      97             :                 /* action not in progress */
      98           0 :                 if (pcmk__str_eq(hp->target, np->target, pcmk__str_casei)
      99           0 :                     && pcmk__str_eq(hp->action, np->action, pcmk__str_none)
     100           0 :                     && (hp->state == np->state)
     101           0 :                     && ((hp->state == st_done)
     102           0 :                         || pcmk__str_eq(hp->delegate, np->delegate,
     103             :                                         pcmk__str_casei))) {
     104             :                         /* purge older hp */
     105           0 :                         stonith_history_free(hp);
     106           0 :                         break;
     107             :                 }
     108             :             }
     109             : 
     110           0 :             if (!np->next) {
     111           0 :                 np->next = hp;
     112           0 :                 break;
     113             :             }
     114             :         }
     115           0 :         hp = hp_next;
     116             :     }
     117             : 
     118           0 :     return new;
     119             : }
     120             : 
     121             : static void
     122           0 : notify_callback(stonith_t * st, stonith_event_t * e)
     123             : {
     124           0 :     if (pcmk__str_eq(async_fence_data.target, e->target, pcmk__str_casei)
     125           0 :         && pcmk__str_eq(async_fence_data.action, e->action, pcmk__str_none)) {
     126             : 
     127           0 :         pcmk__set_result(&async_fence_data.result,
     128             :                          stonith__event_exit_status(e),
     129           0 :                          stonith__event_execution_status(e),
     130             :                          stonith__event_exit_reason(e));
     131           0 :         g_main_loop_quit(mainloop);
     132             :     }
     133           0 : }
     134             : 
     135             : static void
     136           0 : fence_callback(stonith_t * stonith, stonith_callback_data_t * data)
     137             : {
     138           0 :     pcmk__set_result(&async_fence_data.result, stonith__exit_status(data),
     139           0 :                      stonith__execution_status(data),
     140             :                      stonith__exit_reason(data));
     141           0 :     g_main_loop_quit(mainloop);
     142           0 : }
     143             : 
     144             : static gboolean
     145           0 : async_fence_helper(gpointer user_data)
     146             : {
     147           0 :     stonith_t *st = async_fence_data.st;
     148           0 :     int call_id = 0;
     149           0 :     int rc = stonith_api_connect_retry(st, async_fence_data.name, 10);
     150           0 :     int timeout = 0;
     151             : 
     152           0 :     if (rc != pcmk_ok) {
     153           0 :         g_main_loop_quit(mainloop);
     154           0 :         pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
     155             :                          PCMK_EXEC_NOT_CONNECTED, pcmk_strerror(rc));
     156           0 :         return TRUE;
     157             :     }
     158             : 
     159           0 :     st->cmds->register_notification(st, PCMK__VALUE_ST_NOTIFY_FENCE,
     160             :                                     notify_callback);
     161             : 
     162           0 :     call_id = st->cmds->fence_with_delay(st,
     163             :                                          st_opt_allow_suicide,
     164             :                                          async_fence_data.target,
     165             :                                          async_fence_data.action,
     166           0 :                                          async_fence_data.timeout/1000,
     167           0 :                                          async_fence_data.tolerance/1000,
     168             :                                          async_fence_data.delay);
     169             : 
     170           0 :     if (call_id < 0) {
     171           0 :         g_main_loop_quit(mainloop);
     172           0 :         pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
     173             :                          PCMK_EXEC_ERROR, pcmk_strerror(call_id));
     174           0 :         return TRUE;
     175             :     }
     176             : 
     177           0 :     timeout = async_fence_data.timeout / 1000;
     178           0 :     if (async_fence_data.delay > 0) {
     179           0 :         timeout += async_fence_data.delay;
     180             :     }
     181           0 :     st->cmds->register_callback(st, call_id, timeout, st_opt_timeout_updates,
     182             :                                 NULL, "callback", fence_callback);
     183           0 :     return TRUE;
     184             : }
     185             : 
     186             : int
     187           0 : pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
     188             :                       const char *name, unsigned int timeout,
     189             :                       unsigned int tolerance, int delay, char **reason)
     190             : {
     191             :     crm_trigger_t *trig;
     192           0 :     int rc = pcmk_rc_ok;
     193             : 
     194           0 :     async_fence_data.st = st;
     195           0 :     async_fence_data.name = strdup(name);
     196           0 :     async_fence_data.target = target;
     197           0 :     async_fence_data.action = action;
     198           0 :     async_fence_data.timeout = timeout;
     199           0 :     async_fence_data.tolerance = tolerance;
     200           0 :     async_fence_data.delay = delay;
     201           0 :     pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR, PCMK_EXEC_UNKNOWN,
     202             :                      NULL);
     203             : 
     204           0 :     trig = mainloop_add_trigger(G_PRIORITY_HIGH, async_fence_helper, NULL);
     205           0 :     mainloop_set_trigger(trig);
     206             : 
     207           0 :     mainloop = g_main_loop_new(NULL, FALSE);
     208           0 :     g_main_loop_run(mainloop);
     209             : 
     210           0 :     free(async_fence_data.name);
     211             : 
     212           0 :     if (reason != NULL) {
     213             :         // Give the caller ownership of the exit reason
     214           0 :         *reason = async_fence_data.result.exit_reason;
     215           0 :         async_fence_data.result.exit_reason = NULL;
     216             :     }
     217           0 :     rc = stonith__result2rc(&async_fence_data.result);
     218           0 :     pcmk__reset_result(&async_fence_data.result);
     219           0 :     return rc;
     220             : }
     221             : 
     222             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     223             : int
     224             : pcmk_request_fencing(stonith_t *st, const char *target, const char *action,
     225             :                      const char *name, unsigned int timeout,
     226             :                      unsigned int tolerance, int delay, char **reason)
     227             : {
     228             :     return pcmk__request_fencing(st, target, action, name, timeout, tolerance,
     229             :                                  delay, reason);
     230             : }
     231             : #endif
     232             : 
     233             : int
     234           0 : pcmk__fence_history(pcmk__output_t *out, stonith_t *st, const char *target,
     235             :                     unsigned int timeout, int verbose, bool broadcast,
     236             :                     bool cleanup)
     237             : {
     238           0 :     stonith_history_t *history = NULL, *hp, *latest = NULL;
     239           0 :     int rc = pcmk_rc_ok;
     240           0 :     int opts = 0;
     241             : 
     242           0 :     if (cleanup) {
     243           0 :         out->info(out, "cleaning up fencing-history%s%s",
     244             :                   target ? " for node " : "", target ? target : "");
     245             :     }
     246           0 :     if (broadcast) {
     247           0 :         out->info(out, "gather fencing-history from all nodes");
     248             :     }
     249             : 
     250           0 :     stonith__set_call_options(opts, target, st_opts);
     251           0 :     if (cleanup) {
     252           0 :         stonith__set_call_options(opts, target, st_opt_cleanup);
     253             :     }
     254           0 :     if (broadcast) {
     255           0 :         stonith__set_call_options(opts, target, st_opt_broadcast);
     256             :     }
     257           0 :     if (pcmk__str_eq(target, "*", pcmk__str_none)) {
     258           0 :         target = NULL;
     259             :     }
     260           0 :     rc = st->cmds->history(st, opts, target, &history, (timeout / 1000));
     261             : 
     262           0 :     if (cleanup) {
     263             :         // Cleanup doesn't return a history list
     264           0 :         stonith_history_free(history);
     265           0 :         return pcmk_legacy2rc(rc);
     266             :     }
     267             : 
     268           0 :     out->begin_list(out, "event", "events", "Fencing history");
     269             : 
     270           0 :     history = stonith__sort_history(history);
     271           0 :     for (hp = history; hp; hp = hp->next) {
     272           0 :         if (hp->state == st_done) {
     273           0 :             latest = hp;
     274             :         }
     275             : 
     276           0 :         if (out->is_quiet(out) || !verbose) {
     277           0 :             continue;
     278             :         }
     279             : 
     280           0 :         out->message(out, "stonith-event", hp, true, false,
     281             :                      stonith__later_succeeded(hp, history),
     282             :                      (uint32_t) pcmk_show_failed_detail);
     283           0 :         out->increment_list(out);
     284             :     }
     285             : 
     286           0 :     if (latest) {
     287           0 :         if (out->is_quiet(out)) {
     288           0 :             out->message(out, "stonith-event", latest, false, true, NULL,
     289             :                          (uint32_t) pcmk_show_failed_detail);
     290           0 :         } else if (!verbose) { // already printed if verbose
     291           0 :             out->message(out, "stonith-event", latest, false, false, NULL,
     292             :                          (uint32_t) pcmk_show_failed_detail);
     293           0 :             out->increment_list(out);
     294             :         }
     295             :     }
     296             : 
     297           0 :     out->end_list(out);
     298             : 
     299           0 :     stonith_history_free(history);
     300           0 :     return pcmk_legacy2rc(rc);
     301             : }
     302             : 
     303             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     304             : int
     305             : pcmk_fence_history(xmlNodePtr *xml, stonith_t *st, const char *target,
     306             :                    unsigned int timeout, bool quiet, int verbose,
     307             :                    bool broadcast, bool cleanup)
     308             : {
     309             :     pcmk__output_t *out = NULL;
     310             :     int rc = pcmk_rc_ok;
     311             : 
     312             :     rc = pcmk__xml_output_new(&out, xml);
     313             :     if (rc != pcmk_rc_ok) {
     314             :         return rc;
     315             :     }
     316             : 
     317             :     stonith__register_messages(out);
     318             : 
     319             :     out->quiet = quiet;
     320             : 
     321             :     rc = pcmk__fence_history(out, st, target, timeout, verbose, broadcast,
     322             :                              cleanup);
     323             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     324             :     return rc;
     325             : }
     326             : #endif
     327             : 
     328             : int
     329           0 : pcmk__fence_installed(pcmk__output_t *out, stonith_t *st, unsigned int timeout)
     330             : {
     331           0 :     stonith_key_value_t *devices = NULL;
     332           0 :     int rc = pcmk_rc_ok;
     333             : 
     334           0 :     rc = st->cmds->list_agents(st, st_opt_sync_call, NULL, &devices,
     335           0 :                                (timeout / 1000));
     336             :     // rc is a negative error code or a positive number of agents
     337           0 :     if (rc < 0) {
     338           0 :         return pcmk_legacy2rc(rc);
     339             :     }
     340             : 
     341           0 :     out->begin_list(out, "fence device", "fence devices",
     342             :                     "Installed fence devices");
     343           0 :     for (stonith_key_value_t *iter = devices; iter != NULL; iter = iter->next) {
     344           0 :         out->list_item(out, "device", "%s", iter->value);
     345             :     }
     346           0 :     out->end_list(out);
     347             : 
     348           0 :     stonith_key_value_freeall(devices, 1, 1);
     349           0 :     return pcmk_rc_ok;
     350             : }
     351             : 
     352             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     353             : int
     354             : pcmk_fence_installed(xmlNodePtr *xml, stonith_t *st, unsigned int timeout)
     355             : {
     356             :     pcmk__output_t *out = NULL;
     357             :     int rc = pcmk_rc_ok;
     358             : 
     359             :     rc = pcmk__xml_output_new(&out, xml);
     360             :     if (rc != pcmk_rc_ok) {
     361             :         return rc;
     362             :     }
     363             : 
     364             :     stonith__register_messages(out);
     365             : 
     366             :     rc = pcmk__fence_installed(out, st, timeout);
     367             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     368             :     return rc;
     369             : }
     370             : #endif
     371             : 
     372             : int
     373           0 : pcmk__fence_last(pcmk__output_t *out, const char *target, bool as_nodeid)
     374             : {
     375           0 :     time_t when = 0;
     376             : 
     377           0 :     if (target == NULL) {
     378           0 :         return pcmk_rc_ok;
     379             :     }
     380             : 
     381           0 :     if (as_nodeid) {
     382           0 :         when = stonith_api_time(atol(target), NULL, FALSE);
     383             :     } else {
     384           0 :         when = stonith_api_time(0, target, FALSE);
     385             :     }
     386             : 
     387           0 :     return out->message(out, "last-fenced", target, when);
     388             : }
     389             : 
     390             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     391             : int
     392             : pcmk_fence_last(xmlNodePtr *xml, const char *target, bool as_nodeid)
     393             : {
     394             :     pcmk__output_t *out = NULL;
     395             :     int rc = pcmk_rc_ok;
     396             : 
     397             :     rc = pcmk__xml_output_new(&out, xml);
     398             :     if (rc != pcmk_rc_ok) {
     399             :         return rc;
     400             :     }
     401             : 
     402             :     stonith__register_messages(out);
     403             : 
     404             :     rc = pcmk__fence_last(out, target, as_nodeid);
     405             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     406             :     return rc;
     407             : }
     408             : #endif
     409             : 
     410             : int
     411           0 : pcmk__fence_list_targets(pcmk__output_t *out, stonith_t *st,
     412             :                          const char *device_id, unsigned int timeout)
     413             : {
     414           0 :     GList *targets = NULL;
     415           0 :     char *lists = NULL;
     416           0 :     int rc = pcmk_rc_ok;
     417             : 
     418           0 :     rc = st->cmds->list(st, st_opts, device_id, &lists, timeout/1000);
     419           0 :     if (rc != pcmk_rc_ok) {
     420           0 :         return pcmk_legacy2rc(rc);
     421             :     }
     422             : 
     423           0 :     targets = stonith__parse_targets(lists);
     424             : 
     425           0 :     out->begin_list(out, "fence target", "fence targets", "Fence Targets");
     426           0 :     while (targets != NULL) {
     427           0 :         out->list_item(out, NULL, "%s", (const char *) targets->data);
     428           0 :         targets = targets->next;
     429             :     }
     430           0 :     out->end_list(out);
     431             : 
     432           0 :     free(lists);
     433           0 :     return rc;
     434             : }
     435             : 
     436             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     437             : int
     438             : pcmk_fence_list_targets(xmlNodePtr *xml, stonith_t *st, const char *device_id,
     439             :                         unsigned int timeout)
     440             : {
     441             :     pcmk__output_t *out = NULL;
     442             :     int rc = pcmk_rc_ok;
     443             : 
     444             :     rc = pcmk__xml_output_new(&out, xml);
     445             :     if (rc != pcmk_rc_ok) {
     446             :         return rc;
     447             :     }
     448             : 
     449             :     stonith__register_messages(out);
     450             : 
     451             :     rc = pcmk__fence_list_targets(out, st, device_id, timeout);
     452             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     453             :     return rc;
     454             : }
     455             : #endif
     456             : 
     457             : int
     458           0 : pcmk__fence_metadata(pcmk__output_t *out, stonith_t *st, const char *agent,
     459             :                      unsigned int timeout)
     460             : {
     461           0 :     char *buffer = NULL;
     462           0 :     int rc = st->cmds->metadata(st, st_opt_sync_call, agent, NULL, &buffer,
     463           0 :                                 timeout/1000);
     464             : 
     465           0 :     if (rc != pcmk_rc_ok) {
     466           0 :         return pcmk_legacy2rc(rc);
     467             :     }
     468             : 
     469           0 :     out->output_xml(out, PCMK_XE_METADATA, buffer);
     470           0 :     free(buffer);
     471           0 :     return rc;
     472             : }
     473             : 
     474             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     475             : int
     476             : pcmk_fence_metadata(xmlNodePtr *xml, stonith_t *st, const char *agent,
     477             :                     unsigned int timeout)
     478             : {
     479             :     pcmk__output_t *out = NULL;
     480             :     int rc = pcmk_rc_ok;
     481             : 
     482             :     rc = pcmk__xml_output_new(&out, xml);
     483             :     if (rc != pcmk_rc_ok) {
     484             :         return rc;
     485             :     }
     486             : 
     487             :     stonith__register_messages(out);
     488             : 
     489             :     rc = pcmk__fence_metadata(out, st, agent, timeout);
     490             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     491             :     return rc;
     492             : }
     493             : #endif
     494             : 
     495             : int
     496           0 : pcmk__fence_registered(pcmk__output_t *out, stonith_t *st, const char *target,
     497             :                        unsigned int timeout)
     498             : {
     499           0 :     stonith_key_value_t *devices = NULL;
     500           0 :     int rc = pcmk_rc_ok;
     501             : 
     502           0 :     rc = st->cmds->query(st, st_opts, target, &devices, timeout/1000);
     503             :     /* query returns a negative error code or a positive number of results. */
     504           0 :     if (rc < 0) {
     505           0 :         return pcmk_legacy2rc(rc);
     506             :     }
     507             : 
     508           0 :     out->begin_list(out, "fence device", "fence devices",
     509             :                     "Registered fence devices");
     510           0 :     for (stonith_key_value_t *iter = devices; iter != NULL; iter = iter->next) {
     511           0 :         out->list_item(out, "device", "%s", iter->value);
     512             :     }
     513           0 :     out->end_list(out);
     514             : 
     515           0 :     stonith_key_value_freeall(devices, 1, 1);
     516             : 
     517             :     /* Return pcmk_rc_ok here, not the number of results.  Callers probably
     518             :      * don't care.
     519             :      */
     520           0 :     return pcmk_rc_ok;
     521             : }
     522             : 
     523             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     524             : int
     525             : pcmk_fence_registered(xmlNodePtr *xml, stonith_t *st, const char *target,
     526             :                       unsigned int timeout)
     527             : {
     528             :     pcmk__output_t *out = NULL;
     529             :     int rc = pcmk_rc_ok;
     530             : 
     531             :     rc = pcmk__xml_output_new(&out, xml);
     532             :     if (rc != pcmk_rc_ok) {
     533             :         return rc;
     534             :     }
     535             : 
     536             :     stonith__register_messages(out);
     537             : 
     538             :     rc = pcmk__fence_registered(out, st, target, timeout);
     539             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     540             :     return rc;
     541             : }
     542             : #endif
     543             : 
     544             : int
     545           0 : pcmk__fence_register_level(stonith_t *st, const char *target, int fence_level,
     546             :                            const stonith_key_value_t *devices)
     547             : {
     548           0 :     return handle_level(st, target, fence_level, devices, true);
     549             : }
     550             : 
     551             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     552             : int
     553             : pcmk_fence_register_level(stonith_t *st, const char *target, int fence_level,
     554             :                           const stonith_key_value_t *devices)
     555             : {
     556             :     return pcmk__fence_register_level(st, target, fence_level, devices);
     557             : }
     558             : #endif
     559             : 
     560             : int
     561           0 : pcmk__fence_unregister_level(stonith_t *st, const char *target, int fence_level)
     562             : {
     563           0 :     return handle_level(st, target, fence_level, NULL, false);
     564             : }
     565             : 
     566             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     567             : int
     568             : pcmk_fence_unregister_level(stonith_t *st, const char *target, int fence_level)
     569             : {
     570             :     return pcmk__fence_unregister_level(st, target, fence_level);
     571             : }
     572             : #endif
     573             : 
     574             : int
     575           0 : pcmk__fence_validate(pcmk__output_t *out, stonith_t *st, const char *agent,
     576             :                      const char *id, const stonith_key_value_t *params,
     577             :                      unsigned int timeout)
     578             : {
     579           0 :     char *output = NULL;
     580           0 :     char *error_output = NULL;
     581             :     int rc;
     582             : 
     583           0 :     rc  = st->cmds->validate(st, st_opt_sync_call, id, NULL, agent, params,
     584           0 :                              timeout/1000, &output, &error_output);
     585           0 :     out->message(out, "validate", agent, id, output, error_output, rc);
     586           0 :     return pcmk_legacy2rc(rc);
     587             : }
     588             : 
     589             : #ifdef BUILD_PUBLIC_LIBPACEMAKER
     590             : int
     591             : pcmk_fence_validate(xmlNodePtr *xml, stonith_t *st, const char *agent,
     592             :                     const char *id, const stonith_key_value_t *params,
     593             :                     unsigned int timeout)
     594             : {
     595             :     pcmk__output_t *out = NULL;
     596             :     int rc = pcmk_rc_ok;
     597             : 
     598             :     rc = pcmk__xml_output_new(&out, xml);
     599             :     if (rc != pcmk_rc_ok) {
     600             :         return rc;
     601             :     }
     602             : 
     603             :     stonith__register_messages(out);
     604             : 
     605             :     rc = pcmk__fence_validate(out, st, agent, id, params, timeout);
     606             :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     607             :     return rc;
     608             : }
     609             : #endif
     610             : 
     611             : int
     612           0 : pcmk__get_fencing_history(stonith_t *st, stonith_history_t **stonith_history,
     613             :                           enum pcmk__fence_history fence_history)
     614             : {
     615           0 :     int rc = pcmk_rc_ok;
     616             : 
     617           0 :     if ((st == NULL) || (st->state == stonith_disconnected)) {
     618           0 :         rc = ENOTCONN;
     619           0 :     } else if (fence_history != pcmk__fence_history_none) {
     620           0 :         rc = st->cmds->history(st, st_opt_sync_call, NULL, stonith_history,
     621             :                                120);
     622             : 
     623           0 :         rc = pcmk_legacy2rc(rc);
     624           0 :         if (rc != pcmk_rc_ok) {
     625           0 :             return rc;
     626             :         }
     627             : 
     628           0 :         *stonith_history = stonith__sort_history(*stonith_history);
     629           0 :         if (fence_history == pcmk__fence_history_reduced) {
     630           0 :             *stonith_history = reduce_fence_history(*stonith_history);
     631             :         }
     632             :     }
     633             : 
     634           0 :     return rc;
     635             : }

Generated by: LCOV version 1.14