pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
attrs.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011-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 #include <stdio.h>
13 
14 #include <crm/common/xml.h>
15 #include <crm/common/scheduler.h>
17 
18 #define OCF_RESKEY_PREFIX "OCF_RESKEY_"
19 #define LRM_TARGET_ENV OCF_RESKEY_PREFIX CRM_META "_" PCMK__META_ON_NODE
20 
37 const char *
39 {
40  if (name == NULL || pcmk__strcase_any_of(name, "auto", "localhost", NULL)) {
41  char buf[128] = OCF_RESKEY_PREFIX;
42  size_t offset = sizeof(OCF_RESKEY_PREFIX) - 1;
44  char *phys_var = crm_meta_name(PCMK__META_PHYSICAL_HOST);
45  const char *target = NULL;
46  const char *host_physical = NULL;
47 
48  snprintf(buf + offset, sizeof(buf) - offset, "%s", target_var);
49  target = getenv(buf);
50 
51  snprintf(buf + offset, sizeof(buf) - offset, "%s", phys_var);
52  host_physical = getenv(buf);
53 
54  // It is important to use the name by which the scheduler knows us
55  if (host_physical
56  && pcmk__str_eq(target, PCMK_VALUE_HOST, pcmk__str_casei)) {
57  name = host_physical;
58 
59  } else {
60  const char *host_pcmk = getenv(LRM_TARGET_ENV);
61 
62  if (host_pcmk) {
63  name = host_pcmk;
64  }
65  }
66  free(target_var);
67  free(phys_var);
68 
69  // TODO? Call pcmk__cluster_local_node_name() if name == NULL
70  // (currently would require linkage against libcrmcluster)
71  return name;
72  } else {
73  return NULL;
74  }
75 }
76 
87 char *
88 pcmk_promotion_score_name(const char *rsc_id)
89 {
90  if (pcmk__str_empty(rsc_id)) {
91  rsc_id = getenv("OCF_RESOURCE_INSTANCE");
92  if (pcmk__str_empty(rsc_id)) {
93  return NULL;
94  }
95  }
96  return crm_strdup_printf("master-%s", rsc_id);
97 }
98 
113 const char *
114 pcmk__node_attr(const pcmk_node_t *node, const char *name, const char *target,
115  enum pcmk__rsc_node node_type)
116 {
117  // @TODO accept a group of enum pcmk__rsc_node flags as node_type
118  const char *value = NULL; // Attribute value to return
119  const char *node_type_s = NULL; // Readable equivalent of node_type
120  const pcmk_node_t *host = NULL;
121  const pcmk_resource_t *container = NULL;
122 
123  if ((node == NULL) || (name == NULL)) {
124  return NULL;
125  }
126 
127  /* Check the node's own attributes unless this is a guest (bundle) node with
128  * the container host as the attribute target.
129  */
130  if (!pcmk__is_guest_or_bundle_node(node)
131  || !pcmk__str_eq(target, PCMK_VALUE_HOST, pcmk__str_casei)) {
132  value = g_hash_table_lookup(node->priv->attrs, name);
133  crm_trace("%s='%s' on %s",
134  name, pcmk__s(value, ""), pcmk__node_name(node));
135  return value;
136  }
137 
138  /* This resource needs attributes set for the container's host instead of
139  * for the container itself (useful when the container uses the host's
140  * storage).
141  */
142  container = node->priv->remote->priv->launcher;
143 
144  switch (node_type) {
146  host = container->priv->assigned_node;
147  if (host == NULL) {
148  crm_trace("Skipping %s lookup for %s because "
149  "its container %s is unassigned",
150  name, pcmk__node_name(node), container->id);
151  return NULL;
152  }
153  node_type_s = "assigned";
154  break;
155 
157  if (container->priv->active_nodes != NULL) {
158  host = container->priv->active_nodes->data;
159  }
160  if (host == NULL) {
161  crm_trace("Skipping %s lookup for %s because "
162  "its container %s is inactive",
163  name, pcmk__node_name(node), container->id);
164  return NULL;
165  }
166  node_type_s = "current";
167  break;
168 
169  default:
170  // Add support for other enum pcmk__rsc_node values if needed
171  pcmk__assert(false);
172  break;
173  }
174 
175  value = g_hash_table_lookup(host->priv->attrs, name);
176  crm_trace("%s='%s' for %s on %s container host %s",
177  name, pcmk__s(value, ""), pcmk__node_name(node), node_type_s,
178  pcmk__node_name(host));
179  return value;
180 }
pcmk__cpg_host_t host
Definition: cpg.c:52
#define OCF_RESKEY_PREFIX
Definition: attrs.c:18
const char * name
Definition: cib.c:26
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1027
#define PCMK_META_CONTAINER_ATTRIBUTE_TARGET
Definition: options.h:85
const char * pcmk__node_attr(const pcmk_node_t *node, const char *name, const char *target, enum pcmk__rsc_node node_type)
Definition: attrs.c:114
Scheduler API.
char * pcmk_promotion_score_name(const char *rsc_id)
Return the name of the node attribute used as a promotion score.
Definition: attrs.c:88
pcmk__node_private_t * priv
Definition: nodes.h:85
#define PCMK_VALUE_HOST
Definition: options.h:161
#define crm_trace(fmt, args...)
Definition: logging.h:372
pcmk__resource_private_t * priv
Definition: resources.h:61
Wrappers for and extensions to libxml2.
#define PCMK__META_PHYSICAL_HOST
#define pcmk__assert(expr)
const char * target
Definition: pcmk_fence.c:31
pcmk__rsc_node
pcmk_resource_t * remote
pcmk_resource_t * launcher
GHashTable * attrs
const char * pcmk__node_attr_target(const char *name)
Definition: attrs.c:38
#define LRM_TARGET_ENV
Definition: attrs.c:19
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
char * crm_meta_name(const char *field)
Get the environment variable equivalent of a meta-attribute name.
Definition: nvpair.c:407