root/lib/services/services_ocf.c

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

DEFINITIONS

This source file includes following definitions.
  1. resources_os_list_ocf_providers
  2. services_os_get_directory_list_provider
  3. resources_os_list_ocf_agents
  4. services__ocf_agent_exists
  5. services__ocf_prepare
  6. services__ocf2ocf

   1 /*
   2  * Copyright 2012-2022 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 #include <stdio.h>
  13 #include <string.h>
  14 #include <sys/stat.h>
  15 
  16 #include <crm/crm.h>
  17 #include <crm/services.h>
  18 #include <crm/services_internal.h>
  19 
  20 #include "services_private.h"
  21 #include "services_ocf.h"
  22 
  23 GList *
  24 resources_os_list_ocf_providers(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26     return get_directory_list(OCF_RA_PATH, FALSE, TRUE);
  27 }
  28 
  29 static GList *
  30 services_os_get_directory_list_provider(const char *root, const char *provider,
     /* [previous][next][first][last][top][bottom][index][help] */
  31                                         gboolean files, gboolean executable)
  32 {
  33     GList *result = NULL;
  34     char *dirs = strdup(root);
  35     char *dir = NULL;
  36     char buffer[PATH_MAX];
  37 
  38     if (pcmk__str_empty(dirs)) {
  39         free(dirs);
  40         return result;
  41     }
  42 
  43     for (dir = strtok(dirs, ":"); dir != NULL; dir = strtok(NULL, ":")) {
  44         GList *tmp = NULL;
  45 
  46         sprintf(buffer, "%s/%s", dir, provider);
  47         tmp = services_os_get_single_directory_list(buffer, files, executable);
  48 
  49         if (tmp) {
  50             result = g_list_concat(result, tmp);
  51         }
  52     }
  53 
  54     free(dirs);
  55 
  56     return result;
  57 }
  58 
  59 GList *
  60 resources_os_list_ocf_agents(const char *provider)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62     GList *gIter = NULL;
  63     GList *result = NULL;
  64     GList *providers = NULL;
  65 
  66     if (provider) {
  67         return services_os_get_directory_list_provider(OCF_RA_PATH, provider,
  68                                                        TRUE, TRUE);
  69     }
  70 
  71     providers = resources_os_list_ocf_providers();
  72     for (gIter = providers; gIter != NULL; gIter = gIter->next) {
  73         GList *tmp1 = result;
  74         GList *tmp2 = resources_os_list_ocf_agents(gIter->data);
  75 
  76         if (tmp2) {
  77             result = g_list_concat(tmp1, tmp2);
  78         }
  79     }
  80     g_list_free_full(providers, free);
  81     return result;
  82 }
  83 
  84 gboolean
  85 services__ocf_agent_exists(const char *provider, const char *agent)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87     gboolean rc = FALSE;
  88     struct stat st;
  89     char *dirs = strdup(OCF_RA_PATH);
  90     char *dir = NULL;
  91     char *buf = NULL;
  92 
  93     if (provider == NULL || agent == NULL || pcmk__str_empty(dirs)) {
  94         free(dirs);
  95         return rc;
  96     }
  97 
  98     for (dir = strtok(dirs, ":"); dir != NULL; dir = strtok(NULL, ":")) {
  99         buf = crm_strdup_printf("%s/%s/%s", dir, provider, agent);
 100         if (stat(buf, &st) == 0) {
 101             free(buf);
 102             rc = TRUE;
 103             break;
 104         }
 105 
 106         free(buf);
 107     }
 108 
 109     free(dirs);
 110 
 111     return rc;
 112 }
 113 
 114 /*!
 115  * \internal
 116  * \brief Prepare an OCF action
 117  *
 118  * \param[in,out] op  Action to prepare
 119  *
 120  * \return Standard Pacemaker return code
 121  */
 122 int
 123 services__ocf_prepare(svc_action_t *op)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125     char *dirs = strdup(OCF_RA_PATH);
 126     struct stat st;
 127 
 128     if (dirs == NULL) {
 129         return ENOMEM;
 130     }
 131 
 132     // Look for agent on path
 133     for (char *dir = strtok(dirs, ":"); dir != NULL; dir = strtok(NULL, ":")) {
 134         char *buf = crm_strdup_printf("%s/%s/%s", dir, op->provider, op->agent);
 135 
 136         if (stat(buf, &st) == 0) {
 137             op->opaque->exec = buf;
 138             break;
 139         }
 140         free(buf);
 141     }
 142     free(dirs);
 143 
 144     if (op->opaque->exec == NULL) {
 145         return ENOENT;
 146     }
 147 
 148     op->opaque->args[0] = strdup(op->opaque->exec);
 149     op->opaque->args[1] = strdup(op->action);
 150     if ((op->opaque->args[0] == NULL) || (op->opaque->args[1] == NULL)) {
 151         return ENOMEM;
 152     }
 153 
 154     return pcmk_rc_ok;
 155 }
 156 
 157 /*!
 158  * \internal
 159  * \brief Map an actual OCF result to a standard OCF result
 160  *
 161  * \param[in] exit_status  Actual OCF agent exit status
 162  *
 163  * \return Standard OCF result
 164  */
 165 enum ocf_exitcode
 166 services__ocf2ocf(int exit_status)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168     switch (exit_status) {
 169         case PCMK_OCF_DEGRADED:
 170         case PCMK_OCF_DEGRADED_PROMOTED:
 171             break;
 172         default:
 173             if ((exit_status < 0) || (exit_status > PCMK_OCF_FAILED_PROMOTED)) {
 174                 exit_status = PCMK_OCF_UNKNOWN_ERROR;
 175             }
 176             break;
 177     }
 178     return (enum ocf_exitcode) exit_status;
 179 }

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