pacemaker  2.0.1-9e909a5bdd
Scalable High-Availability cluster resource manager
st_rhcs.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 #include <crm_internal.h>
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <glib.h>
14 #include <dirent.h>
15 
16 #include <crm/crm.h>
17 #include <crm/stonith-ng.h>
18 #include <crm/fencing/internal.h>
19 
28 int
30 {
31  // Essentially: ls -1 @sbin_dir@/fence_*
32 
33  int count = 0;
34  struct dirent **namelist;
35  int file_num = scandir(RH_STONITH_DIR, &namelist, 0, alphasort);
36 
37  if (file_num > 0) {
38  struct stat prop;
39  char buffer[FILENAME_MAX + 1];
40 
41  while (file_num--) {
42  if ('.' == namelist[file_num]->d_name[0]) {
43  free(namelist[file_num]);
44  continue;
45 
46  } else if (!crm_starts_with(namelist[file_num]->d_name,
48  free(namelist[file_num]);
49  continue;
50  }
51 
52  snprintf(buffer, FILENAME_MAX, "%s/%s", RH_STONITH_DIR,
53  namelist[file_num]->d_name);
54  if (stat(buffer, &prop) == 0 && S_ISREG(prop.st_mode)) {
55  *devices = stonith_key_value_add(*devices, NULL,
56  namelist[file_num]->d_name);
57  count++;
58  }
59 
60  free(namelist[file_num]);
61  }
62  free(namelist);
63  }
64  return count;
65 }
66 
76 int
77 stonith__rhcs_metadata(const char *agent, int timeout, char **output)
78 {
79  char *buffer = NULL;
80  xmlNode *xml = NULL;
81  xmlNode *actions = NULL;
82  xmlXPathObject *xpathObj = NULL;
83  stonith_action_t *action = stonith_action_create(agent, "metadata", NULL, 0,
84  5, NULL, NULL);
85  int rc = stonith__execute(action);
86 
87  if (rc < 0) {
88  crm_warn("Could not execute metadata action for %s: %s "
89  CRM_XS " rc=%d", agent, pcmk_strerror(rc), rc);
91  return rc;
92  }
93 
94  stonith__action_result(action, &rc, &buffer, NULL);
96  if (rc < 0) {
97  crm_warn("Metadata action for %s failed: %s " CRM_XS "rc=%d",
98  agent, pcmk_strerror(rc), rc);
99  free(buffer);
100  return rc;
101  }
102 
103  if (buffer == NULL) {
104  crm_warn("Metadata action for %s returned no data", agent);
105  return -ENODATA;
106  }
107 
108  xml = string2xml(buffer);
109  free(buffer);
110  buffer = NULL;
111  if (xml == NULL) {
112  crm_warn("Metadata for %s is invalid", agent);
114  }
115 
116  xpathObj = xpath_search(xml, "//actions");
117  if (numXpathResults(xpathObj) > 0) {
118  actions = getXpathResult(xpathObj, 0);
119  }
120  freeXpathObject(xpathObj);
121 
122  // Add start and stop (implemented by pacemaker, not agent) to meta-data
123  xpathObj = xpath_search(xml, "//action[@name='stop']");
124  if (numXpathResults(xpathObj) <= 0) {
125  xmlNode *tmp = NULL;
126 
127  tmp = create_xml_node(actions, "action");
128  crm_xml_add(tmp, "name", "stop");
129  crm_xml_add(tmp, "timeout", CRM_DEFAULT_OP_TIMEOUT_S);
130 
131  tmp = create_xml_node(actions, "action");
132  crm_xml_add(tmp, "name", "start");
133  crm_xml_add(tmp, "timeout", CRM_DEFAULT_OP_TIMEOUT_S);
134  }
135  freeXpathObject(xpathObj);
136 
137  // Fudge metadata so port isn't required in config (pacemaker adds it)
138  xpathObj = xpath_search(xml, "//parameter[@name='port']");
139  if (numXpathResults(xpathObj) > 0) {
140  xmlNode *tmp = getXpathResult(xpathObj, 0);
141 
142  crm_xml_add(tmp, "required", "0");
143  }
144  freeXpathObject(xpathObj);
145 
146  buffer = dump_xml_formatted_with_text(xml);
147  free_xml(xml);
148  if (buffer == NULL) {
150  }
151  if (output) {
152  *output = buffer;
153  } else {
154  free(buffer);
155  }
156  return pcmk_ok;
157 }
158 
159 bool
160 stonith__agent_is_rhcs(const char *agent)
161 {
162  struct stat prop;
163  char *buffer = crm_strdup_printf(RH_STONITH_DIR "/%s", agent);
164  int rc = stat(buffer, &prop);
165 
166  free(buffer);
167  return (rc >= 0) && S_ISREG(prop.st_mode);
168 }
169 
170 int
171 stonith__rhcs_validate(stonith_t *st, int call_options, const char *target,
172  const char *agent, GHashTable *params, int timeout,
173  char **output, char **error_output)
174 {
175  int rc = pcmk_ok;
176  stonith_action_t *action = stonith_action_create(agent, "validate-all",
177  target, 0, timeout, params,
178  NULL);
179 
180  rc = stonith__execute(action);
181  if (rc == pcmk_ok) {
182  stonith__action_result(action, &rc, output, error_output);
183  }
184  stonith__destroy_action(action);
185  return rc;
186 }
void stonith__destroy_action(stonith_action_t *action)
Definition: st_client.c:616
struct stonith_action_s stonith_action_t
Definition: internal.h:15
#define pcmk_err_schema_validation
Definition: results.h:40
A dumping ground.
bool stonith__agent_is_rhcs(const char *agent)
Definition: st_rhcs.c:160
const char * pcmk_strerror(int rc)
Definition: results.c:184
void stonith__action_result(stonith_action_t *action, int *rc, char **output, char **error_output)
Definition: st_client.c:641
int stonith__execute(stonith_action_t *action)
Definition: st_client.c:1085
int alphasort(const void *dirent1, const void *dirent2)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:212
int stonith__rhcs_metadata(const char *agent, int timeout, char **output)
Execute RHCS-compatible agent&#39;s meta-data action.
Definition: st_rhcs.c:77
bool crm_starts_with(const char *str, const char *prefix)
Check whether a string starts with a certain sequence.
Definition: strings.c:243
xmlNode * string2xml(const char *input)
Definition: xml.c:2056
stonith_key_value_t * stonith_key_value_add(stonith_key_value_t *kvp, const char *key, const char *value)
Definition: st_client.c:2304
#define crm_warn(fmt, args...)
Definition: logging.h:250
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1888
#define CRM_DEFAULT_OP_TIMEOUT_S
Definition: util.h:119
#define RH_STONITH_PREFIX
Definition: config.h:586
void free_xml(xmlNode *child)
Definition: xml.c:2012
#define CRM_XS
Definition: logging.h:43
#define ENODATA
Definition: portability.h:156
int stonith__list_rhcs_agents(stonith_key_value_t **devices)
Definition: st_rhcs.c:29
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:145
Fencing aka. STONITH.
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:64
#define pcmk_ok
Definition: results.h:35
stonith_action_t * stonith_action_create(const char *agent, const char *_action, const char *victim, uint32_t victim_nodeid, int timeout, GHashTable *device_args, GHashTable *port_map)
Definition: st_client.c:670
int stonith__rhcs_validate(stonith_t *st, int call_options, const char *target, const char *agent, GHashTable *params, int timeout, char **output, char **error_output)
Definition: st_rhcs.c:171
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:45
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:3144
#define RH_STONITH_DIR
Definition: config.h:583