LCOV - code coverage report
Current view: top level - common - results.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 44 482 9.1 %
Date: 2024-05-07 11:09:47 Functions: 5 22 22.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2004-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 Lesser General Public License
       7             :  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
       8             :  */
       9             : 
      10             : #include <crm_internal.h>
      11             : 
      12             : #ifndef _GNU_SOURCE
      13             : #  define _GNU_SOURCE
      14             : #endif
      15             : 
      16             : #include <bzlib.h>
      17             : #include <errno.h>
      18             : #include <netdb.h>
      19             : #include <stdlib.h>
      20             : #include <string.h>
      21             : #include <qb/qbdefs.h>
      22             : 
      23             : #include <crm/common/mainloop.h>
      24             : #include <crm/common/xml.h>
      25             : 
      26           0 : G_DEFINE_QUARK(pcmk-rc-error-quark, pcmk__rc_error)
      27           0 : G_DEFINE_QUARK(pcmk-exitc-error-quark, pcmk__exitc_error)
      28             : 
      29             : // General (all result code types)
      30             : 
      31             : /*!
      32             :  * \brief Get the name and description of a given result code
      33             :  *
      34             :  * A result code can be interpreted as a member of any one of several families.
      35             :  *
      36             :  * \param[in]  code  The result code to look up
      37             :  * \param[in]  type  How \p code should be interpreted
      38             :  * \param[out] name  Where to store the result code's name
      39             :  * \param[out] desc  Where to store the result code's description
      40             :  *
      41             :  * \return Standard Pacemaker return code
      42             :  */
      43             : int
      44           0 : pcmk_result_get_strings(int code, enum pcmk_result_type type, const char **name,
      45             :                         const char **desc)
      46             : {
      47           0 :     const char *code_name = NULL;
      48           0 :     const char *code_desc = NULL;
      49             : 
      50           0 :     switch (type) {
      51           0 :         case pcmk_result_legacy:
      52           0 :             code_name = pcmk_errorname(code);
      53           0 :             code_desc = pcmk_strerror(code);
      54           0 :             break;
      55           0 :         case pcmk_result_rc:
      56           0 :             code_name = pcmk_rc_name(code);
      57           0 :             code_desc = pcmk_rc_str(code);
      58           0 :             break;
      59           0 :         case pcmk_result_exitcode:
      60           0 :             code_name = crm_exit_name(code);
      61           0 :             code_desc = crm_exit_str((crm_exit_t) code);
      62           0 :             break;
      63           0 :         default:
      64           0 :             return pcmk_rc_undetermined;
      65             :     }
      66             : 
      67           0 :     if (name != NULL) {
      68           0 :         *name = code_name;
      69             :     }
      70             :     
      71           0 :     if (desc != NULL) {
      72           0 :         *desc = code_desc;
      73             :     }
      74           0 :     return pcmk_rc_ok;
      75             : }
      76             : 
      77             : /*!
      78             :  * \internal
      79             :  * \brief Get the lower and upper bounds of a result code family
      80             :  *
      81             :  * \param[in]   type    Type of result code
      82             :  * \param[out]  lower   Where to store the lower bound
      83             :  * \param[out]  upper   Where to store the upper bound
      84             :  *
      85             :  * \return Standard Pacemaker return code
      86             :  *
      87             :  * \note There is no true upper bound on standard Pacemaker return codes or
      88             :  *       legacy return codes. All system \p errno values are valid members of
      89             :  *       these result code families, and there is no global upper limit nor a
      90             :  *       constant by which to refer to the highest \p errno value on a given
      91             :  *       system.
      92             :  */
      93             : int
      94           0 : pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
      95             : {
      96           0 :     CRM_ASSERT((lower != NULL) && (upper != NULL));
      97             : 
      98           0 :     switch (type) {
      99           0 :         case pcmk_result_legacy:
     100           0 :             *lower = pcmk_ok;
     101           0 :             *upper = 256;   // should be enough for almost any system error code
     102           0 :             break;
     103           0 :         case pcmk_result_rc:
     104           0 :             *lower = pcmk_rc_error - pcmk__n_rc + 1;
     105           0 :             *upper = 256;
     106           0 :             break;
     107           0 :         case pcmk_result_exitcode:
     108           0 :             *lower = CRM_EX_OK;
     109           0 :             *upper = CRM_EX_MAX;
     110           0 :             break;
     111           0 :         default:
     112           0 :             *lower = 0;
     113           0 :             *upper = -1;
     114           0 :             return pcmk_rc_undetermined;
     115             :     }
     116           0 :     return pcmk_rc_ok;
     117             : }
     118             : 
     119             : // @COMPAT Legacy function return codes
     120             : 
     121             : //! \deprecated Use standard return codes and pcmk_rc_name() instead
     122             : const char *
     123           0 : pcmk_errorname(int rc)
     124             : {
     125           0 :     rc = abs(rc);
     126           0 :     switch (rc) {
     127           0 :         case pcmk_err_generic: return "pcmk_err_generic";
     128           0 :         case pcmk_err_no_quorum: return "pcmk_err_no_quorum";
     129           0 :         case pcmk_err_schema_validation: return "pcmk_err_schema_validation";
     130           0 :         case pcmk_err_transform_failed: return "pcmk_err_transform_failed";
     131           0 :         case pcmk_err_old_data: return "pcmk_err_old_data";
     132           0 :         case pcmk_err_diff_failed: return "pcmk_err_diff_failed";
     133           0 :         case pcmk_err_diff_resync: return "pcmk_err_diff_resync";
     134           0 :         case pcmk_err_cib_modified: return "pcmk_err_cib_modified";
     135           0 :         case pcmk_err_cib_backup: return "pcmk_err_cib_backup";
     136           0 :         case pcmk_err_cib_save: return "pcmk_err_cib_save";
     137           0 :         case pcmk_err_cib_corrupt: return "pcmk_err_cib_corrupt";
     138           0 :         case pcmk_err_multiple: return "pcmk_err_multiple";
     139           0 :         case pcmk_err_node_unknown: return "pcmk_err_node_unknown";
     140           0 :         case pcmk_err_already: return "pcmk_err_already";
     141           0 :         case pcmk_err_bad_nvpair: return "pcmk_err_bad_nvpair";
     142           0 :         case pcmk_err_unknown_format: return "pcmk_err_unknown_format";
     143           0 :         default: return pcmk_rc_name(rc); // system errno
     144             :     }
     145             : }
     146             : 
     147             : //! \deprecated Use standard return codes and pcmk_rc_str() instead
     148             : const char *
     149           0 : pcmk_strerror(int rc)
     150             : {
     151           0 :     return pcmk_rc_str(pcmk_legacy2rc(rc));
     152             : }
     153             : 
     154             : // Standard Pacemaker API return codes
     155             : 
     156             : /* This array is used only for nonzero values of pcmk_rc_e. Its values must be
     157             :  * kept in the exact reverse order of the enum value numbering (i.e. add new
     158             :  * values to the end of the array).
     159             :  */
     160             : static const struct pcmk__rc_info {
     161             :     const char *name;
     162             :     const char *desc;
     163             :     int legacy_rc;
     164             : } pcmk__rcs[] = {
     165             :     { "pcmk_rc_error",
     166             :       "Error",
     167             :       -pcmk_err_generic,
     168             :     },
     169             :     { "pcmk_rc_unknown_format",
     170             :       "Unknown output format",
     171             :       -pcmk_err_unknown_format,
     172             :     },
     173             :     { "pcmk_rc_bad_nvpair",
     174             :       "Bad name/value pair given",
     175             :       -pcmk_err_bad_nvpair,
     176             :     },
     177             :     { "pcmk_rc_already",
     178             :       "Already in requested state",
     179             :       -pcmk_err_already,
     180             :     },
     181             :     { "pcmk_rc_node_unknown",
     182             :       "Node not found",
     183             :       -pcmk_err_node_unknown,
     184             :     },
     185             :     { "pcmk_rc_multiple",
     186             :       "Resource active on multiple nodes",
     187             :       -pcmk_err_multiple,
     188             :     },
     189             :     { "pcmk_rc_cib_corrupt",
     190             :       "Could not parse on-disk configuration",
     191             :       -pcmk_err_cib_corrupt,
     192             :     },
     193             :     { "pcmk_rc_cib_save",
     194             :       "Could not save new configuration to disk",
     195             :       -pcmk_err_cib_save,
     196             :     },
     197             :     { "pcmk_rc_cib_backup",
     198             :       "Could not archive previous configuration",
     199             :       -pcmk_err_cib_backup,
     200             :     },
     201             :     { "pcmk_rc_cib_modified",
     202             :       "On-disk configuration was manually modified",
     203             :       -pcmk_err_cib_modified,
     204             :     },
     205             :     { "pcmk_rc_diff_resync",
     206             :       "Application of update diff failed, requesting full refresh",
     207             :       -pcmk_err_diff_resync,
     208             :     },
     209             :     { "pcmk_rc_diff_failed",
     210             :       "Application of update diff failed",
     211             :       -pcmk_err_diff_failed,
     212             :     },
     213             :     { "pcmk_rc_old_data",
     214             :       "Update was older than existing configuration",
     215             :       -pcmk_err_old_data,
     216             :     },
     217             :     { "pcmk_rc_transform_failed",
     218             :       "Schema transform failed",
     219             :       -pcmk_err_transform_failed,
     220             :     },
     221             :     { "pcmk_rc_schema_unchanged",
     222             :       "Schema is already the latest available",
     223             :       -pcmk_err_schema_unchanged,
     224             :     },
     225             :     { "pcmk_rc_schema_validation",
     226             :       "Update does not conform to the configured schema",
     227             :       -pcmk_err_schema_validation,
     228             :     },
     229             :     { "pcmk_rc_no_quorum",
     230             :       "Operation requires quorum",
     231             :       -pcmk_err_no_quorum,
     232             :     },
     233             :     { "pcmk_rc_ipc_unauthorized",
     234             :       "IPC server is blocked by unauthorized process",
     235             :       -pcmk_err_generic,
     236             :     },
     237             :     { "pcmk_rc_ipc_unresponsive",
     238             :       "IPC server is unresponsive",
     239             :       -pcmk_err_generic,
     240             :     },
     241             :     { "pcmk_rc_ipc_pid_only",
     242             :       "IPC server process is active but not accepting connections",
     243             :       -pcmk_err_generic,
     244             :     },
     245             :     { "pcmk_rc_op_unsatisfied",
     246             :       "Not applicable under current conditions",
     247             :       -pcmk_err_generic,
     248             :     },
     249             :     { "pcmk_rc_undetermined",
     250             :       "Result undetermined",
     251             :       -pcmk_err_generic,
     252             :     },
     253             :     { "pcmk_rc_before_range",
     254             :       "Result occurs before given range",
     255             :       -pcmk_err_generic,
     256             :     },
     257             :     { "pcmk_rc_within_range",
     258             :       "Result occurs within given range",
     259             :       -pcmk_err_generic,
     260             :     },
     261             :     { "pcmk_rc_after_range",
     262             :       "Result occurs after given range",
     263             :       -pcmk_err_generic,
     264             :     },
     265             :     { "pcmk_rc_no_output",
     266             :       "Output message produced no output",
     267             :       -pcmk_err_generic,
     268             :     },
     269             :     { "pcmk_rc_no_input",
     270             :       "Input file not available",
     271             :       -pcmk_err_generic,
     272             :     },
     273             :     { "pcmk_rc_underflow",
     274             :       "Value too small to be stored in data type",
     275             :       -pcmk_err_generic,
     276             :     },
     277             :     { "pcmk_rc_dot_error",
     278             :       "Error writing dot(1) file",
     279             :       -pcmk_err_generic,
     280             :     },
     281             :     { "pcmk_rc_graph_error",
     282             :       "Error writing graph file",
     283             :       -pcmk_err_generic,
     284             :     },
     285             :     { "pcmk_rc_invalid_transition",
     286             :       "Cluster simulation produced invalid transition",
     287             :       -pcmk_err_generic,
     288             :     },
     289             :     { "pcmk_rc_unpack_error",
     290             :       "Unable to parse CIB XML",
     291             :       -pcmk_err_generic,
     292             :     },
     293             :     { "pcmk_rc_duplicate_id",
     294             :       "Two or more XML elements have the same ID",
     295             :       -pcmk_err_generic,
     296             :     },
     297             :     { "pcmk_rc_disabled",
     298             :       "Disabled",
     299             :       -pcmk_err_generic,
     300             :     },
     301             :     { "pcmk_rc_bad_input",
     302             :       "Bad input value provided",
     303             :       -pcmk_err_generic,
     304             :     },
     305             :     { "pcmk_rc_bad_xml_patch",
     306             :       "Bad XML patch format",
     307             :       -pcmk_err_generic,
     308             :     },
     309             :     { "pcmk_rc_no_transaction",
     310             :       "No active transaction found",
     311             :       -pcmk_err_generic,
     312             :     },
     313             :     { "pcmk_rc_ns_resolution",
     314             :       "Nameserver resolution error",
     315             :       -pcmk_err_generic,
     316             :     },
     317             :     { "pcmk_rc_compression",
     318             :       "Compression/decompression error",
     319             :       -pcmk_err_generic,
     320             :     },
     321             : };
     322             : 
     323             : /*!
     324             :  * \internal
     325             :  * \brief The number of <tt>enum pcmk_rc_e</tt> values, excluding \c pcmk_rc_ok
     326             :  *
     327             :  * This constant stores the number of negative standard Pacemaker return codes.
     328             :  * These represent Pacemaker-custom error codes. The count does not include
     329             :  * positive system error numbers, nor does it include \c pcmk_rc_ok (success).
     330             :  */
     331             : const size_t pcmk__n_rc = PCMK__NELEM(pcmk__rcs);
     332             : 
     333             : /*!
     334             :  * \brief Get a return code constant name as a string
     335             :  *
     336             :  * \param[in] rc  Integer return code to convert
     337             :  *
     338             :  * \return String of constant name corresponding to rc
     339             :  */
     340             : const char *
     341           4 : pcmk_rc_name(int rc)
     342             : {
     343           4 :     if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
     344           1 :         return pcmk__rcs[pcmk_rc_error - rc].name;
     345             :     }
     346           3 :     switch (rc) {
     347           2 :         case pcmk_rc_ok:        return "pcmk_rc_ok";
     348           0 :         case E2BIG:             return "E2BIG";
     349           0 :         case EACCES:            return "EACCES";
     350           0 :         case EADDRINUSE:        return "EADDRINUSE";
     351           0 :         case EADDRNOTAVAIL:     return "EADDRNOTAVAIL";
     352           0 :         case EAFNOSUPPORT:      return "EAFNOSUPPORT";
     353           0 :         case EAGAIN:            return "EAGAIN";
     354           0 :         case EALREADY:          return "EALREADY";
     355           0 :         case EBADF:             return "EBADF";
     356           0 :         case EBADMSG:           return "EBADMSG";
     357           0 :         case EBUSY:             return "EBUSY";
     358           0 :         case ECANCELED:         return "ECANCELED";
     359           0 :         case ECHILD:            return "ECHILD";
     360           0 :         case ECOMM:             return "ECOMM";
     361           0 :         case ECONNABORTED:      return "ECONNABORTED";
     362           0 :         case ECONNREFUSED:      return "ECONNREFUSED";
     363           0 :         case ECONNRESET:        return "ECONNRESET";
     364             :         /* case EDEADLK:        return "EDEADLK"; */
     365           0 :         case EDESTADDRREQ:      return "EDESTADDRREQ";
     366           0 :         case EDOM:              return "EDOM";
     367           0 :         case EDQUOT:            return "EDQUOT";
     368           0 :         case EEXIST:            return "EEXIST";
     369           0 :         case EFAULT:            return "EFAULT";
     370           0 :         case EFBIG:             return "EFBIG";
     371           0 :         case EHOSTDOWN:         return "EHOSTDOWN";
     372           0 :         case EHOSTUNREACH:      return "EHOSTUNREACH";
     373           0 :         case EIDRM:             return "EIDRM";
     374           0 :         case EILSEQ:            return "EILSEQ";
     375           0 :         case EINPROGRESS:       return "EINPROGRESS";
     376           0 :         case EINTR:             return "EINTR";
     377           0 :         case EINVAL:            return "EINVAL";
     378           0 :         case EIO:               return "EIO";
     379           0 :         case EISCONN:           return "EISCONN";
     380           0 :         case EISDIR:            return "EISDIR";
     381           0 :         case ELIBACC:           return "ELIBACC";
     382           0 :         case ELOOP:             return "ELOOP";
     383           0 :         case EMFILE:            return "EMFILE";
     384           0 :         case EMLINK:            return "EMLINK";
     385           0 :         case EMSGSIZE:          return "EMSGSIZE";
     386             : #ifdef EMULTIHOP // Not available on OpenBSD
     387           0 :         case EMULTIHOP:         return "EMULTIHOP";
     388             : #endif
     389           0 :         case ENAMETOOLONG:      return "ENAMETOOLONG";
     390           0 :         case ENETDOWN:          return "ENETDOWN";
     391           0 :         case ENETRESET:         return "ENETRESET";
     392           0 :         case ENETUNREACH:       return "ENETUNREACH";
     393           0 :         case ENFILE:            return "ENFILE";
     394           0 :         case ENOBUFS:           return "ENOBUFS";
     395           0 :         case ENODATA:           return "ENODATA";
     396           0 :         case ENODEV:            return "ENODEV";
     397           0 :         case ENOENT:            return "ENOENT";
     398           0 :         case ENOEXEC:           return "ENOEXEC";
     399           0 :         case ENOKEY:            return "ENOKEY";
     400           0 :         case ENOLCK:            return "ENOLCK";
     401             : #ifdef ENOLINK // Not available on OpenBSD
     402           0 :         case ENOLINK:           return "ENOLINK";
     403             : #endif
     404           0 :         case ENOMEM:            return "ENOMEM";
     405           0 :         case ENOMSG:            return "ENOMSG";
     406           0 :         case ENOPROTOOPT:       return "ENOPROTOOPT";
     407           0 :         case ENOSPC:            return "ENOSPC";
     408             : #ifdef ENOSR
     409           0 :         case ENOSR:             return "ENOSR";
     410             : #endif
     411             : #ifdef ENOSTR
     412           0 :         case ENOSTR:            return "ENOSTR";
     413             : #endif
     414           0 :         case ENOSYS:            return "ENOSYS";
     415           0 :         case ENOTBLK:           return "ENOTBLK";
     416           0 :         case ENOTCONN:          return "ENOTCONN";
     417           0 :         case ENOTDIR:           return "ENOTDIR";
     418           0 :         case ENOTEMPTY:         return "ENOTEMPTY";
     419           0 :         case ENOTSOCK:          return "ENOTSOCK";
     420             : #if ENOTSUP != EOPNOTSUPP
     421             :         case ENOTSUP:           return "ENOTSUP";
     422             : #endif
     423           0 :         case ENOTTY:            return "ENOTTY";
     424           0 :         case ENOTUNIQ:          return "ENOTUNIQ";
     425           0 :         case ENXIO:             return "ENXIO";
     426           0 :         case EOPNOTSUPP:        return "EOPNOTSUPP";
     427           0 :         case EOVERFLOW:         return "EOVERFLOW";
     428           0 :         case EPERM:             return "EPERM";
     429           0 :         case EPFNOSUPPORT:      return "EPFNOSUPPORT";
     430           0 :         case EPIPE:             return "EPIPE";
     431           0 :         case EPROTO:            return "EPROTO";
     432           0 :         case EPROTONOSUPPORT:   return "EPROTONOSUPPORT";
     433           0 :         case EPROTOTYPE:        return "EPROTOTYPE";
     434           0 :         case ERANGE:            return "ERANGE";
     435           0 :         case EREMOTE:           return "EREMOTE";
     436           0 :         case EREMOTEIO:         return "EREMOTEIO";
     437           0 :         case EROFS:             return "EROFS";
     438           0 :         case ESHUTDOWN:         return "ESHUTDOWN";
     439           0 :         case ESPIPE:            return "ESPIPE";
     440           0 :         case ESOCKTNOSUPPORT:   return "ESOCKTNOSUPPORT";
     441           0 :         case ESRCH:             return "ESRCH";
     442           0 :         case ESTALE:            return "ESTALE";
     443           0 :         case ETIME:             return "ETIME";
     444           0 :         case ETIMEDOUT:         return "ETIMEDOUT";
     445           0 :         case ETXTBSY:           return "ETXTBSY";
     446             : #ifdef EUNATCH
     447           0 :         case EUNATCH:           return "EUNATCH";
     448             : #endif
     449           0 :         case EUSERS:            return "EUSERS";
     450             :         /* case EWOULDBLOCK:    return "EWOULDBLOCK"; */
     451           0 :         case EXDEV:             return "EXDEV";
     452             : 
     453             : #ifdef EBADE // Not available on OS X
     454           0 :         case EBADE:             return "EBADE";
     455           0 :         case EBADFD:            return "EBADFD";
     456           0 :         case EBADSLT:           return "EBADSLT";
     457           0 :         case EDEADLOCK:         return "EDEADLOCK";
     458           0 :         case EBADR:             return "EBADR";
     459           0 :         case EBADRQC:           return "EBADRQC";
     460           0 :         case ECHRNG:            return "ECHRNG";
     461             : #ifdef EISNAM // Not available on OS X, Illumos, Solaris
     462           0 :         case EISNAM:            return "EISNAM";
     463           0 :         case EKEYEXPIRED:       return "EKEYEXPIRED";
     464           0 :         case EKEYREVOKED:       return "EKEYREVOKED";
     465             : #endif
     466           0 :         case EKEYREJECTED:      return "EKEYREJECTED";
     467           0 :         case EL2HLT:            return "EL2HLT";
     468           0 :         case EL2NSYNC:          return "EL2NSYNC";
     469           0 :         case EL3HLT:            return "EL3HLT";
     470           0 :         case EL3RST:            return "EL3RST";
     471           0 :         case ELIBBAD:           return "ELIBBAD";
     472           0 :         case ELIBMAX:           return "ELIBMAX";
     473           0 :         case ELIBSCN:           return "ELIBSCN";
     474           0 :         case ELIBEXEC:          return "ELIBEXEC";
     475             : #ifdef ENOMEDIUM // Not available on OS X, Illumos, Solaris
     476           0 :         case ENOMEDIUM:         return "ENOMEDIUM";
     477           0 :         case EMEDIUMTYPE:       return "EMEDIUMTYPE";
     478             : #endif
     479           0 :         case ENONET:            return "ENONET";
     480           0 :         case ENOPKG:            return "ENOPKG";
     481           0 :         case EREMCHG:           return "EREMCHG";
     482           0 :         case ERESTART:          return "ERESTART";
     483           0 :         case ESTRPIPE:          return "ESTRPIPE";
     484             : #ifdef EUCLEAN // Not available on OS X, Illumos, Solaris
     485           0 :         case EUCLEAN:           return "EUCLEAN";
     486             : #endif
     487           0 :         case EXFULL:            return "EXFULL";
     488             : #endif // EBADE
     489           1 :         default:                return "Unknown";
     490             :     }
     491             : }
     492             : 
     493             : /*!
     494             :  * \brief Get a user-friendly description of a return code
     495             :  *
     496             :  * \param[in] rc  Integer return code to convert
     497             :  *
     498             :  * \return String description of rc
     499             :  */
     500             : const char *
     501          15 : pcmk_rc_str(int rc)
     502             : {
     503          15 :     if (rc == pcmk_rc_ok) {
     504           1 :         return "OK";
     505             :     }
     506          14 :     if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
     507           1 :         return pcmk__rcs[pcmk_rc_error - rc].desc;
     508             :     }
     509          13 :     if (rc < 0) {
     510           1 :         return "Error";
     511             :     }
     512             : 
     513             :     // Handle values that could be defined by system or by portability.h
     514             :     switch (rc) {
     515             : #ifdef PCMK__ENOTUNIQ
     516             :         case ENOTUNIQ:      return "Name not unique on network";
     517             : #endif
     518             : #ifdef PCMK__ECOMM
     519             :         case ECOMM:         return "Communication error on send";
     520             : #endif
     521             : #ifdef PCMK__ELIBACC
     522             :         case ELIBACC:       return "Can not access a needed shared library";
     523             : #endif
     524             : #ifdef PCMK__EREMOTEIO
     525             :         case EREMOTEIO:     return "Remote I/O error";
     526             : #endif
     527             : #ifdef PCMK__ENOKEY
     528             :         case ENOKEY:        return "Required key not available";
     529             : #endif
     530             : #ifdef PCMK__ENODATA
     531             :         case ENODATA:       return "No data available";
     532             : #endif
     533             : #ifdef PCMK__ETIME
     534             :         case ETIME:         return "Timer expired";
     535             : #endif
     536             : #ifdef PCMK__EKEYREJECTED
     537             :         case EKEYREJECTED:  return "Key was rejected by service";
     538             : #endif
     539          12 :         default:            return strerror(rc);
     540             :     }
     541             : }
     542             : 
     543             : // This returns negative values for errors
     544             : //! \deprecated Use standard return codes instead
     545             : int
     546           0 : pcmk_rc2legacy(int rc)
     547             : {
     548           0 :     if (rc >= 0) {
     549           0 :         return -rc; // OK or system errno
     550             :     }
     551           0 :     if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
     552           0 :         return pcmk__rcs[pcmk_rc_error - rc].legacy_rc;
     553             :     }
     554           0 :     return -pcmk_err_generic;
     555             : }
     556             : 
     557             : //! \deprecated Use standard return codes instead
     558             : int
     559           0 : pcmk_legacy2rc(int legacy_rc)
     560             : {
     561           0 :     legacy_rc = abs(legacy_rc);
     562           0 :     switch (legacy_rc) {
     563           0 :         case pcmk_err_no_quorum:            return pcmk_rc_no_quorum;
     564           0 :         case pcmk_err_schema_validation:    return pcmk_rc_schema_validation;
     565           0 :         case pcmk_err_schema_unchanged:     return pcmk_rc_schema_unchanged;
     566           0 :         case pcmk_err_transform_failed:     return pcmk_rc_transform_failed;
     567           0 :         case pcmk_err_old_data:             return pcmk_rc_old_data;
     568           0 :         case pcmk_err_diff_failed:          return pcmk_rc_diff_failed;
     569           0 :         case pcmk_err_diff_resync:          return pcmk_rc_diff_resync;
     570           0 :         case pcmk_err_cib_modified:         return pcmk_rc_cib_modified;
     571           0 :         case pcmk_err_cib_backup:           return pcmk_rc_cib_backup;
     572           0 :         case pcmk_err_cib_save:             return pcmk_rc_cib_save;
     573           0 :         case pcmk_err_cib_corrupt:          return pcmk_rc_cib_corrupt;
     574           0 :         case pcmk_err_multiple:             return pcmk_rc_multiple;
     575           0 :         case pcmk_err_node_unknown:         return pcmk_rc_node_unknown;
     576           0 :         case pcmk_err_already:              return pcmk_rc_already;
     577           0 :         case pcmk_err_bad_nvpair:           return pcmk_rc_bad_nvpair;
     578           0 :         case pcmk_err_unknown_format:       return pcmk_rc_unknown_format;
     579           0 :         case pcmk_err_generic:              return pcmk_rc_error;
     580           0 :         case pcmk_ok:                       return pcmk_rc_ok;
     581           0 :         default:                            return legacy_rc; // system errno
     582             :     }
     583             : }
     584             : 
     585             : // Exit status codes
     586             : 
     587             : const char *
     588           1 : crm_exit_name(crm_exit_t exit_code)
     589             : {
     590           1 :     switch (exit_code) {
     591           1 :         case CRM_EX_OK: return "CRM_EX_OK";
     592           0 :         case CRM_EX_ERROR: return "CRM_EX_ERROR";
     593           0 :         case CRM_EX_INVALID_PARAM: return "CRM_EX_INVALID_PARAM";
     594           0 :         case CRM_EX_UNIMPLEMENT_FEATURE: return "CRM_EX_UNIMPLEMENT_FEATURE";
     595           0 :         case CRM_EX_INSUFFICIENT_PRIV: return "CRM_EX_INSUFFICIENT_PRIV";
     596           0 :         case CRM_EX_NOT_INSTALLED: return "CRM_EX_NOT_INSTALLED";
     597           0 :         case CRM_EX_NOT_CONFIGURED: return "CRM_EX_NOT_CONFIGURED";
     598           0 :         case CRM_EX_NOT_RUNNING: return "CRM_EX_NOT_RUNNING";
     599           0 :         case CRM_EX_PROMOTED: return "CRM_EX_PROMOTED";
     600           0 :         case CRM_EX_FAILED_PROMOTED: return "CRM_EX_FAILED_PROMOTED";
     601           0 :         case CRM_EX_USAGE: return "CRM_EX_USAGE";
     602           0 :         case CRM_EX_DATAERR: return "CRM_EX_DATAERR";
     603           0 :         case CRM_EX_NOINPUT: return "CRM_EX_NOINPUT";
     604           0 :         case CRM_EX_NOUSER: return "CRM_EX_NOUSER";
     605           0 :         case CRM_EX_NOHOST: return "CRM_EX_NOHOST";
     606           0 :         case CRM_EX_UNAVAILABLE: return "CRM_EX_UNAVAILABLE";
     607           0 :         case CRM_EX_SOFTWARE: return "CRM_EX_SOFTWARE";
     608           0 :         case CRM_EX_OSERR: return "CRM_EX_OSERR";
     609           0 :         case CRM_EX_OSFILE: return "CRM_EX_OSFILE";
     610           0 :         case CRM_EX_CANTCREAT: return "CRM_EX_CANTCREAT";
     611           0 :         case CRM_EX_IOERR: return "CRM_EX_IOERR";
     612           0 :         case CRM_EX_TEMPFAIL: return "CRM_EX_TEMPFAIL";
     613           0 :         case CRM_EX_PROTOCOL: return "CRM_EX_PROTOCOL";
     614           0 :         case CRM_EX_NOPERM: return "CRM_EX_NOPERM";
     615           0 :         case CRM_EX_CONFIG: return "CRM_EX_CONFIG";
     616           0 :         case CRM_EX_FATAL: return "CRM_EX_FATAL";
     617           0 :         case CRM_EX_PANIC: return "CRM_EX_PANIC";
     618           0 :         case CRM_EX_DISCONNECT: return "CRM_EX_DISCONNECT";
     619           0 :         case CRM_EX_DIGEST: return "CRM_EX_DIGEST";
     620           0 :         case CRM_EX_NOSUCH: return "CRM_EX_NOSUCH";
     621           0 :         case CRM_EX_QUORUM: return "CRM_EX_QUORUM";
     622           0 :         case CRM_EX_UNSAFE: return "CRM_EX_UNSAFE";
     623           0 :         case CRM_EX_EXISTS: return "CRM_EX_EXISTS";
     624           0 :         case CRM_EX_MULTIPLE: return "CRM_EX_MULTIPLE";
     625           0 :         case CRM_EX_EXPIRED: return "CRM_EX_EXPIRED";
     626           0 :         case CRM_EX_NOT_YET_IN_EFFECT: return "CRM_EX_NOT_YET_IN_EFFECT";
     627           0 :         case CRM_EX_INDETERMINATE: return "CRM_EX_INDETERMINATE";
     628           0 :         case CRM_EX_UNSATISFIED: return "CRM_EX_UNSATISFIED";
     629           0 :         case CRM_EX_OLD: return "CRM_EX_OLD";
     630           0 :         case CRM_EX_TIMEOUT: return "CRM_EX_TIMEOUT";
     631           0 :         case CRM_EX_DEGRADED: return "CRM_EX_DEGRADED";
     632           0 :         case CRM_EX_DEGRADED_PROMOTED: return "CRM_EX_DEGRADED_PROMOTED";
     633           0 :         case CRM_EX_NONE: return "CRM_EX_NONE";
     634           0 :         case CRM_EX_MAX: return "CRM_EX_UNKNOWN";
     635             :     }
     636           0 :     return "CRM_EX_UNKNOWN";
     637             : }
     638             : 
     639             : const char *
     640          55 : crm_exit_str(crm_exit_t exit_code)
     641             : {
     642          55 :     switch (exit_code) {
     643          29 :         case CRM_EX_OK: return "OK";
     644           0 :         case CRM_EX_ERROR: return "Error occurred";
     645           0 :         case CRM_EX_INVALID_PARAM: return "Invalid parameter";
     646           0 :         case CRM_EX_UNIMPLEMENT_FEATURE: return "Unimplemented";
     647           4 :         case CRM_EX_INSUFFICIENT_PRIV: return "Insufficient privileges";
     648           0 :         case CRM_EX_NOT_INSTALLED: return "Not installed";
     649           0 :         case CRM_EX_NOT_CONFIGURED: return "Not configured";
     650           0 :         case CRM_EX_NOT_RUNNING: return "Not running";
     651           0 :         case CRM_EX_PROMOTED: return "Promoted";
     652           0 :         case CRM_EX_FAILED_PROMOTED: return "Failed in promoted role";
     653           0 :         case CRM_EX_USAGE: return "Incorrect usage";
     654           0 :         case CRM_EX_DATAERR: return "Invalid data given";
     655           0 :         case CRM_EX_NOINPUT: return "Input file not available";
     656           0 :         case CRM_EX_NOUSER: return "User does not exist";
     657           0 :         case CRM_EX_NOHOST: return "Host does not exist";
     658           0 :         case CRM_EX_UNAVAILABLE: return "Necessary service unavailable";
     659           7 :         case CRM_EX_SOFTWARE: return "Internal software bug";
     660           0 :         case CRM_EX_OSERR: return "Operating system error occurred";
     661           0 :         case CRM_EX_OSFILE: return "System file not available";
     662           0 :         case CRM_EX_CANTCREAT: return "Cannot create output file";
     663           0 :         case CRM_EX_IOERR: return "I/O error occurred";
     664           0 :         case CRM_EX_TEMPFAIL: return "Temporary failure, try again";
     665           0 :         case CRM_EX_PROTOCOL: return "Protocol violated";
     666           0 :         case CRM_EX_NOPERM: return "Insufficient privileges";
     667           0 :         case CRM_EX_CONFIG: return "Invalid configuration";
     668           0 :         case CRM_EX_FATAL: return "Fatal error occurred, will not respawn";
     669           0 :         case CRM_EX_PANIC: return "System panic required";
     670           6 :         case CRM_EX_DISCONNECT: return "Not connected";
     671           0 :         case CRM_EX_DIGEST: return "Digest mismatch";
     672           6 :         case CRM_EX_NOSUCH: return "No such object";
     673           0 :         case CRM_EX_QUORUM: return "Quorum required";
     674           0 :         case CRM_EX_UNSAFE: return "Operation not safe";
     675           0 :         case CRM_EX_EXISTS: return "Requested item already exists";
     676           1 :         case CRM_EX_MULTIPLE: return "Multiple items match request";
     677           0 :         case CRM_EX_EXPIRED: return "Requested item has expired";
     678           0 :         case CRM_EX_NOT_YET_IN_EFFECT: return "Requested item is not yet in effect";
     679           0 :         case CRM_EX_INDETERMINATE: return "Could not determine status";
     680           0 :         case CRM_EX_UNSATISFIED: return "Not applicable under current conditions";
     681           0 :         case CRM_EX_OLD: return "Update was older than existing configuration";
     682           0 :         case CRM_EX_TIMEOUT: return "Timeout occurred";
     683           0 :         case CRM_EX_DEGRADED: return "Service is active but might fail soon";
     684           0 :         case CRM_EX_DEGRADED_PROMOTED: return "Service is promoted but might fail soon";
     685           0 :         case CRM_EX_NONE: return "No exit status available";
     686           0 :         case CRM_EX_MAX: return "Error occurred";
     687             :     }
     688           2 :     if ((exit_code > 128) && (exit_code < CRM_EX_MAX)) {
     689           1 :         return "Interrupted by signal";
     690             :     }
     691           1 :     return "Unknown exit status";
     692             : }
     693             : 
     694             : /*!
     695             :  * \brief Map a function return code to the most similar exit code
     696             :  *
     697             :  * \param[in] rc  Function return code
     698             :  *
     699             :  * \return Most similar exit code
     700             :  */
     701             : crm_exit_t
     702          67 : pcmk_rc2exitc(int rc)
     703             : {
     704          67 :     switch (rc) {
     705          31 :         case pcmk_rc_ok:
     706             :         case pcmk_rc_no_output: // quiet mode, or nothing to output
     707          31 :             return CRM_EX_OK;
     708             : 
     709           0 :         case pcmk_rc_no_quorum:
     710           0 :             return CRM_EX_QUORUM;
     711             : 
     712           0 :         case pcmk_rc_old_data:
     713           0 :             return CRM_EX_OLD;
     714             : 
     715           0 :         case pcmk_rc_schema_validation:
     716             :         case pcmk_rc_transform_failed:
     717             :         case pcmk_rc_unpack_error:
     718           0 :             return CRM_EX_CONFIG;
     719             : 
     720           0 :         case pcmk_rc_bad_nvpair:
     721           0 :             return CRM_EX_INVALID_PARAM;
     722             : 
     723           4 :         case EACCES:
     724           4 :             return CRM_EX_INSUFFICIENT_PRIV;
     725             : 
     726          14 :         case EBADF:
     727             :         case EINVAL:
     728             :         case EFAULT:
     729             :         case ENOSYS:
     730             :         case EOVERFLOW:
     731             :         case pcmk_rc_underflow:
     732             :         case pcmk_rc_compression:
     733          14 :             return CRM_EX_SOFTWARE;
     734             : 
     735           0 :         case EBADMSG:
     736             :         case EMSGSIZE:
     737             :         case ENOMSG:
     738             :         case ENOPROTOOPT:
     739             :         case EPROTO:
     740             :         case EPROTONOSUPPORT:
     741             :         case EPROTOTYPE:
     742           0 :             return CRM_EX_PROTOCOL;
     743             : 
     744           0 :         case ECOMM:
     745             :         case ENOMEM:
     746           0 :             return CRM_EX_OSERR;
     747             : 
     748          10 :         case ECONNABORTED:
     749             :         case ECONNREFUSED:
     750             :         case ECONNRESET:
     751             :         case ENOTCONN:
     752          10 :             return CRM_EX_DISCONNECT;
     753             : 
     754           0 :         case EEXIST:
     755             :         case pcmk_rc_already:
     756           0 :             return CRM_EX_EXISTS;
     757             : 
     758           0 :         case EIO:
     759             :         case pcmk_rc_dot_error:
     760             :         case pcmk_rc_graph_error:
     761           0 :             return CRM_EX_IOERR;
     762             : 
     763           0 :         case ENOTSUP:
     764             : #if EOPNOTSUPP != ENOTSUP
     765             :         case EOPNOTSUPP:
     766             : #endif
     767           0 :             return CRM_EX_UNIMPLEMENT_FEATURE;
     768             : 
     769           0 :         case ENOTUNIQ:
     770             :         case pcmk_rc_multiple:
     771           0 :             return CRM_EX_MULTIPLE;
     772             : 
     773           6 :         case ENODEV:
     774             :         case ENOENT:
     775             :         case ENXIO:
     776             :         case pcmk_rc_no_transaction:
     777             :         case pcmk_rc_unknown_format:
     778           6 :             return CRM_EX_NOSUCH;
     779             : 
     780           0 :         case pcmk_rc_node_unknown:
     781             :         case pcmk_rc_ns_resolution:
     782           0 :             return CRM_EX_NOHOST;
     783             : 
     784           0 :         case ETIME:
     785             :         case ETIMEDOUT:
     786           0 :             return CRM_EX_TIMEOUT;
     787             : 
     788           0 :         case EAGAIN:
     789             :         case EBUSY:
     790           0 :             return CRM_EX_UNSATISFIED;
     791             : 
     792           0 :         case pcmk_rc_before_range:
     793           0 :             return CRM_EX_NOT_YET_IN_EFFECT;
     794             : 
     795           0 :         case pcmk_rc_after_range:
     796           0 :             return CRM_EX_EXPIRED;
     797             : 
     798           0 :         case pcmk_rc_undetermined:
     799           0 :             return CRM_EX_INDETERMINATE;
     800             : 
     801           0 :         case pcmk_rc_op_unsatisfied:
     802           0 :             return CRM_EX_UNSATISFIED;
     803             : 
     804           0 :         case pcmk_rc_within_range:
     805           0 :             return CRM_EX_OK;
     806             : 
     807           0 :         case pcmk_rc_no_input:
     808           0 :             return CRM_EX_NOINPUT;
     809             : 
     810           1 :         case pcmk_rc_duplicate_id:
     811           1 :             return CRM_EX_MULTIPLE;
     812             : 
     813           0 :         case pcmk_rc_bad_input:
     814             :         case pcmk_rc_bad_xml_patch:
     815           0 :             return CRM_EX_DATAERR;
     816             : 
     817           1 :         default:
     818           1 :             return CRM_EX_ERROR;
     819             :     }
     820             : }
     821             : 
     822             : /*!
     823             :  * \brief Map a function return code to the most similar OCF exit code
     824             :  *
     825             :  * \param[in] rc  Function return code
     826             :  *
     827             :  * \return Most similar OCF exit code
     828             :  */
     829             : enum ocf_exitcode
     830           0 : pcmk_rc2ocf(int rc)
     831             : {
     832           0 :     switch (rc) {
     833           0 :         case pcmk_rc_ok:
     834           0 :             return PCMK_OCF_OK;
     835             : 
     836           0 :         case pcmk_rc_bad_nvpair:
     837           0 :             return PCMK_OCF_INVALID_PARAM;
     838             : 
     839           0 :         case EACCES:
     840           0 :             return PCMK_OCF_INSUFFICIENT_PRIV;
     841             : 
     842           0 :         case ENOTSUP:
     843             : #if EOPNOTSUPP != ENOTSUP
     844             :         case EOPNOTSUPP:
     845             : #endif
     846           0 :             return PCMK_OCF_UNIMPLEMENT_FEATURE;
     847             : 
     848           0 :         default:
     849           0 :             return PCMK_OCF_UNKNOWN_ERROR;
     850             :     }
     851             : }
     852             : 
     853             : 
     854             : // Other functions
     855             : 
     856             : /*!
     857             :  * \brief Map a getaddrinfo() return code to the most similar Pacemaker
     858             :  *        return code
     859             :  *
     860             :  * \param[in] gai  getaddrinfo() return code
     861             :  *
     862             :  * \return Most similar Pacemaker return code
     863             :  */
     864             : int
     865           0 : pcmk__gaierror2rc(int gai)
     866             : {
     867           0 :     switch (gai) {
     868           0 :         case 0:
     869           0 :             return pcmk_rc_ok;
     870             : 
     871           0 :         case EAI_AGAIN:
     872           0 :             return EAGAIN;
     873             : 
     874           0 :         case EAI_BADFLAGS:
     875             :         case EAI_SERVICE:
     876           0 :             return EINVAL;
     877             : 
     878           0 :         case EAI_FAMILY:
     879           0 :             return EAFNOSUPPORT;
     880             : 
     881           0 :         case EAI_MEMORY:
     882           0 :             return ENOMEM;
     883             : 
     884           0 :         case EAI_NONAME:
     885           0 :             return pcmk_rc_node_unknown;
     886             : 
     887           0 :         case EAI_SOCKTYPE:
     888           0 :             return ESOCKTNOSUPPORT;
     889             : 
     890           0 :         case EAI_SYSTEM:
     891           0 :             return errno;
     892             : 
     893           0 :         default:
     894           0 :             return pcmk_rc_ns_resolution;
     895             :     }
     896             : }
     897             : 
     898             : /*!
     899             :  * \brief Map a bz2 return code to the most similar Pacemaker return code
     900             :  *
     901             :  * \param[in] bz2  bz2 return code
     902             :  *
     903             :  * \return Most similar Pacemaker return code
     904             :  */
     905             : int
     906           0 : pcmk__bzlib2rc(int bz2)
     907             : {
     908           0 :     switch (bz2) {
     909           0 :         case BZ_OK:
     910             :         case BZ_RUN_OK:
     911             :         case BZ_FLUSH_OK:
     912             :         case BZ_FINISH_OK:
     913             :         case BZ_STREAM_END:
     914           0 :             return pcmk_rc_ok;
     915             : 
     916           0 :         case BZ_MEM_ERROR:
     917           0 :             return ENOMEM;
     918             : 
     919           0 :         case BZ_DATA_ERROR:
     920             :         case BZ_DATA_ERROR_MAGIC:
     921             :         case BZ_UNEXPECTED_EOF:
     922           0 :             return pcmk_rc_bad_input;
     923             : 
     924           0 :         case BZ_IO_ERROR:
     925           0 :             return EIO;
     926             : 
     927           0 :         case BZ_OUTBUFF_FULL:
     928           0 :             return EFBIG;
     929             : 
     930           0 :         default:
     931           0 :             return pcmk_rc_compression;
     932             :     }
     933             : }
     934             : 
     935             : crm_exit_t
     936           0 : crm_exit(crm_exit_t rc)
     937             : {
     938             :     /* A compiler could theoretically use any type for crm_exit_t, but an int
     939             :      * should always hold it, so cast to int to keep static analysis happy.
     940             :      */
     941           0 :     if ((((int) rc) < 0) || (((int) rc) > CRM_EX_MAX)) {
     942           0 :         rc = CRM_EX_ERROR;
     943             :     }
     944             : 
     945           0 :     mainloop_cleanup();
     946           0 :     crm_xml_cleanup();
     947             : 
     948           0 :     free(pcmk__our_nodename);
     949             : 
     950           0 :     if (crm_system_name) {
     951           0 :         crm_info("Exiting %s " CRM_XS " with status %d", crm_system_name, rc);
     952           0 :         free(crm_system_name);
     953             :     } else {
     954           0 :         crm_trace("Exiting with status %d", rc);
     955             :     }
     956           0 :     pcmk__free_common_logger();
     957           0 :     qb_log_fini(); // Don't log anything after this point
     958             : 
     959           0 :     exit(rc);
     960             : }
     961             : 
     962             : /*
     963             :  * External action results
     964             :  */
     965             : 
     966             : /*!
     967             :  * \internal
     968             :  * \brief Set the result of an action
     969             :  *
     970             :  * \param[out] result        Where to set action result
     971             :  * \param[in]  exit_status   OCF exit status to set
     972             :  * \param[in]  exec_status   Execution status to set
     973             :  * \param[in]  exit_reason   Human-friendly description of event to set
     974             :  */
     975             : void
     976           0 : pcmk__set_result(pcmk__action_result_t *result, int exit_status,
     977             :                  enum pcmk_exec_status exec_status, const char *exit_reason)
     978             : {
     979           0 :     if (result == NULL) {
     980           0 :         return;
     981             :     }
     982             : 
     983           0 :     result->exit_status = exit_status;
     984           0 :     result->execution_status = exec_status;
     985             : 
     986           0 :     if (!pcmk__str_eq(result->exit_reason, exit_reason, pcmk__str_none)) {
     987           0 :         free(result->exit_reason);
     988           0 :         result->exit_reason = (exit_reason == NULL)? NULL : strdup(exit_reason);
     989             :     }
     990             : }
     991             : 
     992             : 
     993             : /*!
     994             :  * \internal
     995             :  * \brief Set the result of an action, with a formatted exit reason
     996             :  *
     997             :  * \param[out] result        Where to set action result
     998             :  * \param[in]  exit_status   OCF exit status to set
     999             :  * \param[in]  exec_status   Execution status to set
    1000             :  * \param[in]  format        printf-style format for a human-friendly
    1001             :  *                           description of reason for result
    1002             :  * \param[in]  ...           arguments for \p format
    1003             :  */
    1004             : G_GNUC_PRINTF(4, 5)
    1005             : void
    1006           0 : pcmk__format_result(pcmk__action_result_t *result, int exit_status,
    1007             :                     enum pcmk_exec_status exec_status,
    1008             :                     const char *format, ...)
    1009             : {
    1010             :     va_list ap;
    1011           0 :     int len = 0;
    1012           0 :     char *reason = NULL;
    1013             : 
    1014           0 :     if (result == NULL) {
    1015           0 :         return;
    1016             :     }
    1017             : 
    1018           0 :     result->exit_status = exit_status;
    1019           0 :     result->execution_status = exec_status;
    1020             : 
    1021           0 :     if (format != NULL) {
    1022           0 :         va_start(ap, format);
    1023           0 :         len = vasprintf(&reason, format, ap);
    1024           0 :         CRM_ASSERT(len > 0);
    1025           0 :         va_end(ap);
    1026             :     }
    1027           0 :     free(result->exit_reason);
    1028           0 :     result->exit_reason = reason;
    1029             : }
    1030             : 
    1031             : /*!
    1032             :  * \internal
    1033             :  * \brief Set the output of an action
    1034             :  *
    1035             :  * \param[out] result         Action result to set output for
    1036             :  * \param[in]  out            Action output to set (must be dynamically
    1037             :  *                            allocated)
    1038             :  * \param[in]  err            Action error output to set (must be dynamically
    1039             :  *                            allocated)
    1040             :  *
    1041             :  * \note \p result will take ownership of \p out and \p err, so the caller
    1042             :  *       should not free them.
    1043             :  */
    1044             : void
    1045           0 : pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
    1046             : {
    1047           0 :     if (result == NULL) {
    1048           0 :         return;
    1049             :     }
    1050             : 
    1051           0 :     free(result->action_stdout);
    1052           0 :     result->action_stdout = out;
    1053             : 
    1054           0 :     free(result->action_stderr);
    1055           0 :     result->action_stderr = err;
    1056             : }
    1057             : 
    1058             : /*!
    1059             :  * \internal
    1060             :  * \brief Clear a result's exit reason, output, and error output
    1061             :  *
    1062             :  * \param[in,out] result  Result to reset
    1063             :  */
    1064             : void
    1065           0 : pcmk__reset_result(pcmk__action_result_t *result)
    1066             : {
    1067           0 :     if (result == NULL) {
    1068           0 :         return;
    1069             :     }
    1070             : 
    1071           0 :     free(result->exit_reason);
    1072           0 :     result->exit_reason = NULL;
    1073             : 
    1074           0 :     free(result->action_stdout);
    1075           0 :     result->action_stdout = NULL;
    1076             : 
    1077           0 :     free(result->action_stderr);
    1078           0 :     result->action_stderr = NULL;
    1079             : }
    1080             : 
    1081             : /*!
    1082             :  * \internal
    1083             :  * \brief Copy the result of an action
    1084             :  *
    1085             :  * \param[in]  src  Result to copy
    1086             :  * \param[out] dst  Where to copy \p src to
    1087             :  */
    1088             : void
    1089           0 : pcmk__copy_result(const pcmk__action_result_t *src, pcmk__action_result_t *dst)
    1090             : {
    1091           0 :     CRM_CHECK((src != NULL) && (dst != NULL), return);
    1092           0 :     dst->exit_status = src->exit_status;
    1093           0 :     dst->execution_status = src->execution_status;
    1094           0 :     dst->exit_reason = pcmk__str_copy(src->exit_reason);
    1095           0 :     dst->action_stdout = pcmk__str_copy(src->action_stdout);
    1096           0 :     dst->action_stderr = pcmk__str_copy(src->action_stderr);
    1097             : }
    1098             : 
    1099             : // Deprecated functions kept only for backward API compatibility
    1100             : // LCOV_EXCL_START
    1101             : 
    1102             : #include <crm/common/results_compat.h>
    1103             : 
    1104             : const char *
    1105             : bz2_strerror(int rc)
    1106             : {
    1107             :     // See ftp://sources.redhat.com/pub/bzip2/docs/manual_3.html#SEC17
    1108             :     switch (rc) {
    1109             :         case BZ_OK:
    1110             :         case BZ_RUN_OK:
    1111             :         case BZ_FLUSH_OK:
    1112             :         case BZ_FINISH_OK:
    1113             :         case BZ_STREAM_END:
    1114             :             return "Ok";
    1115             :         case BZ_CONFIG_ERROR:
    1116             :             return "libbz2 has been improperly compiled on your platform";
    1117             :         case BZ_SEQUENCE_ERROR:
    1118             :             return "library functions called in the wrong order";
    1119             :         case BZ_PARAM_ERROR:
    1120             :             return "parameter is out of range or otherwise incorrect";
    1121             :         case BZ_MEM_ERROR:
    1122             :             return "memory allocation failed";
    1123             :         case BZ_DATA_ERROR:
    1124             :             return "data integrity error is detected during decompression";
    1125             :         case BZ_DATA_ERROR_MAGIC:
    1126             :             return "the compressed stream does not start with the correct magic bytes";
    1127             :         case BZ_IO_ERROR:
    1128             :             return "error reading or writing in the compressed file";
    1129             :         case BZ_UNEXPECTED_EOF:
    1130             :             return "compressed file finishes before the logical end of stream is detected";
    1131             :         case BZ_OUTBUFF_FULL:
    1132             :             return "output data will not fit into the buffer provided";
    1133             :     }
    1134             :     return "Data compression error";
    1135             : }
    1136             : 
    1137             : crm_exit_t
    1138             : crm_errno2exit(int rc)
    1139             : {
    1140             :     return pcmk_rc2exitc(pcmk_legacy2rc(rc));
    1141             : }
    1142             : 
    1143             : // LCOV_EXCL_STOP
    1144             : // End deprecated API

Generated by: LCOV version 1.14