pacemaker  2.1.8-3980678f03
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 #ifndef _GNU_SOURCE
11 # define _GNU_SOURCE
12 #endif
13 
14 #include <crm_internal.h>
15 
16 #include <stdio.h>
17 
18 #include <crm/common/xml.h>
19 #include <crm/common/scheduler.h>
21 
22 #define OCF_RESKEY_PREFIX "OCF_RESKEY_"
23 #define LRM_TARGET_ENV OCF_RESKEY_PREFIX CRM_META "_" PCMK__META_ON_NODE
24 
41 const char *
43 {
44  if (name == NULL || pcmk__strcase_any_of(name, "auto", "localhost", NULL)) {
45  char buf[128] = OCF_RESKEY_PREFIX;
46  size_t offset = sizeof(OCF_RESKEY_PREFIX) - 1;
48  char *phys_var = crm_meta_name(PCMK__META_PHYSICAL_HOST);
49  const char *target = NULL;
50  const char *host_physical = NULL;
51 
52  snprintf(buf + offset, sizeof(buf) - offset, "%s", target_var);
53  target = getenv(buf);
54 
55  snprintf(buf + offset, sizeof(buf) - offset, "%s", phys_var);
56  host_physical = getenv(buf);
57 
58  // It is important to use the name by which the scheduler knows us
59  if (host_physical
60  && pcmk__str_eq(target, PCMK_VALUE_HOST, pcmk__str_casei)) {
61  name = host_physical;
62 
63  } else {
64  const char *host_pcmk = getenv(LRM_TARGET_ENV);
65 
66  if (host_pcmk) {
67  name = host_pcmk;
68  }
69  }
70  free(target_var);
71  free(phys_var);
72 
73  // TODO? Call pcmk__cluster_local_node_name() if name == NULL
74  // (currently would require linkage against libcrmcluster)
75  return name;
76  } else {
77  return NULL;
78  }
79 }
80 
91 char *
92 pcmk_promotion_score_name(const char *rsc_id)
93 {
94  if (pcmk__str_empty(rsc_id)) {
95  rsc_id = getenv("OCF_RESOURCE_INSTANCE");
96  if (pcmk__str_empty(rsc_id)) {
97  return NULL;
98  }
99  }
100  return crm_strdup_printf("master-%s", rsc_id);
101 }
102 
117 const char *
118 pcmk__node_attr(const pcmk_node_t *node, const char *name, const char *target,
120 {
121  const char *value = NULL; // Attribute value to return
122  const char *node_type_s = NULL; // Readable equivalent of node_type
123  const pcmk_node_t *host = NULL;
124  const pcmk_resource_t *container = NULL;
125 
126  if ((node == NULL) || (name == NULL)) {
127  return NULL;
128  }
129 
130  /* Check the node's own attributes unless this is a guest (bundle) node with
131  * the container host as the attribute target.
132  */
133  if (!pcmk__is_guest_or_bundle_node(node)
134  || !pcmk__str_eq(target, PCMK_VALUE_HOST, pcmk__str_casei)) {
135  value = g_hash_table_lookup(node->details->attrs, name);
136  crm_trace("%s='%s' on %s",
137  name, pcmk__s(value, ""), pcmk__node_name(node));
138  return value;
139  }
140 
141  /* This resource needs attributes set for the container's host instead of
142  * for the container itself (useful when the container uses the host's
143  * storage).
144  */
145  container = node->details->remote_rsc->container;
146 
147  switch (node_type) {
149  host = container->allocated_to;
150  if (host == NULL) {
151  crm_trace("Skipping %s lookup for %s because "
152  "its container %s is unassigned",
153  name, pcmk__node_name(node), container->id);
154  return NULL;
155  }
156  node_type_s = "assigned";
157  break;
158 
160  if (container->running_on != NULL) {
161  host = container->running_on->data;
162  }
163  if (host == NULL) {
164  crm_trace("Skipping %s lookup for %s because "
165  "its container %s is inactive",
166  name, pcmk__node_name(node), container->id);
167  return NULL;
168  }
169  node_type_s = "current";
170  break;
171 
172  default:
173  // Add support for other enum pcmk__rsc_node values if needed
174  CRM_ASSERT(false);
175  break;
176  }
177 
178  value = g_hash_table_lookup(host->details->attrs, name);
179  crm_trace("%s='%s' for %s on %s container host %s",
180  name, pcmk__s(value, ""), pcmk__node_name(node), node_type_s,
181  pcmk__node_name(host));
182  return value;
183 }
pcmk__cpg_host_t host
Definition: cpg.c:52
#define OCF_RESKEY_PREFIX
Definition: attrs.c:22
GHashTable * attrs
Definition: nodes.h:142
node_type
Definition: nodes.h:38
const char * name
Definition: cib.c:26
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1026
#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:118
Where resource is assigned.
pcmk_resource_t * container
Definition: resources.h:476
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:92
#define PCMK_VALUE_HOST
Definition: options.h:160
#define crm_trace(fmt, args...)
Definition: logging.h:404
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
struct pe_node_shared_s * details
Definition: nodes.h:167
Wrappers for and extensions to libxml2.
#define PCMK__META_PHYSICAL_HOST
const char * target
Definition: pcmk_fence.c:29
pcmk__rsc_node
#define CRM_ASSERT(expr)
Definition: results.h:42
pcmk_node_t * allocated_to
Definition: resources.h:447
GList * running_on
Definition: resources.h:456
const char * pcmk__node_attr_target(const char *name)
Definition: attrs.c:42
#define LRM_TARGET_ENV
Definition: attrs.c:23
pcmk_resource_t * remote_rsc
Definition: nodes.h:135
Where resource is running.
char * crm_meta_name(const char *field)
Get the environment variable equivalent of a meta-attribute name.
Definition: nvpair.c:959