This source file includes following definitions.
- attrd_create_attribute
- attrd_update_dampening
- attrd_add_value_xml
- attrd_clear_value_seen
- attrd_populate_attribute
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <errno.h>
13 #include <stdbool.h>
14 #include <stdlib.h>
15 #include <glib.h>
16
17 #include <crm/msg_xml.h>
18 #include <crm/common/logging.h>
19 #include <crm/common/results.h>
20 #include <crm/common/strings_internal.h>
21 #include <crm/common/xml.h>
22
23 #include "pacemaker-attrd.h"
24
25 static attribute_t *
26 attrd_create_attribute(xmlNode *xml)
27 {
28 int dampen = 0;
29 const char *value = crm_element_value(xml, PCMK__XA_ATTR_DAMPENING);
30 attribute_t *a = calloc(1, sizeof(attribute_t));
31
32 CRM_ASSERT(a != NULL);
33
34 a->id = crm_element_value_copy(xml, PCMK__XA_ATTR_NAME);
35 a->set = crm_element_value_copy(xml, PCMK__XA_ATTR_SET);
36 a->uuid = crm_element_value_copy(xml, PCMK__XA_ATTR_UUID);
37 a->values = pcmk__strikey_table(NULL, attrd_free_attribute_value);
38
39 crm_element_value_int(xml, PCMK__XA_ATTR_IS_PRIVATE, &a->is_private);
40
41 a->user = crm_element_value_copy(xml, PCMK__XA_ATTR_USER);
42 crm_trace("Performing all %s operations as user '%s'", a->id, a->user);
43
44 if (value != NULL) {
45 dampen = crm_get_msec(value);
46 }
47 crm_trace("Created attribute %s with %s write delay", a->id,
48 (a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms));
49
50 if(dampen > 0) {
51 a->timeout_ms = dampen;
52 a->timer = attrd_add_timer(a->id, a->timeout_ms, a);
53 } else if (dampen < 0) {
54 crm_warn("Ignoring invalid delay %s for attribute %s", value, a->id);
55 }
56
57 g_hash_table_replace(attributes, a->id, a);
58 return a;
59 }
60
61 static int
62 attrd_update_dampening(attribute_t *a, xmlNode *xml, const char *attr)
63 {
64 const char *dvalue = crm_element_value(xml, PCMK__XA_ATTR_DAMPENING);
65 int dampen = 0;
66
67 if (dvalue == NULL) {
68 crm_warn("Could not update %s: peer did not specify value for delay",
69 attr);
70 return EINVAL;
71 }
72
73 dampen = crm_get_msec(dvalue);
74 if (dampen < 0) {
75 crm_warn("Could not update %s: invalid delay value %dms (%s)",
76 attr, dampen, dvalue);
77 return EINVAL;
78 }
79
80 if (a->timeout_ms != dampen) {
81 mainloop_timer_del(a->timer);
82 a->timeout_ms = dampen;
83 if (dampen > 0) {
84 a->timer = attrd_add_timer(attr, a->timeout_ms, a);
85 crm_info("Update attribute %s delay to %dms (%s)",
86 attr, dampen, dvalue);
87 } else {
88 a->timer = NULL;
89 crm_info("Update attribute %s to remove delay", attr);
90 }
91
92
93
94
95 attrd_write_or_elect_attribute(a);
96 }
97
98 return pcmk_rc_ok;
99 }
100
101 GHashTable *attributes = NULL;
102
103
104
105
106
107
108
109
110
111
112
113
114 xmlNode *
115 attrd_add_value_xml(xmlNode *parent, const attribute_t *a,
116 const attribute_value_t *v, bool force_write)
117 {
118 xmlNode *xml = create_xml_node(parent, __func__);
119
120 crm_xml_add(xml, PCMK__XA_ATTR_NAME, a->id);
121 crm_xml_add(xml, PCMK__XA_ATTR_SET, a->set);
122 crm_xml_add(xml, PCMK__XA_ATTR_UUID, a->uuid);
123 crm_xml_add(xml, PCMK__XA_ATTR_USER, a->user);
124 pcmk__xe_add_node(xml, v->nodename, v->nodeid);
125 if (v->is_remote != 0) {
126 crm_xml_add_int(xml, PCMK__XA_ATTR_IS_REMOTE, 1);
127 }
128 crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current);
129 crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, a->timeout_ms / 1000);
130 crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE, a->is_private);
131 crm_xml_add_int(xml, PCMK__XA_ATTR_FORCE, force_write);
132
133 return xml;
134 }
135
136 void
137 attrd_clear_value_seen(void)
138 {
139 GHashTableIter aIter;
140 GHashTableIter vIter;
141 attribute_t *a;
142 attribute_value_t *v = NULL;
143
144 g_hash_table_iter_init(&aIter, attributes);
145 while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
146 g_hash_table_iter_init(&vIter, a->values);
147 while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & v)) {
148 v->seen = FALSE;
149 crm_trace("Clear seen flag %s[%s] = %s.", a->id, v->nodename, v->current);
150 }
151 }
152 }
153
154 attribute_t *
155 attrd_populate_attribute(xmlNode *xml, const char *attr)
156 {
157 attribute_t *a = NULL;
158 bool update_both = false;
159
160 const char *op = crm_element_value(xml, PCMK__XA_TASK);
161
162
163 update_both = pcmk__str_eq(op, PCMK__ATTRD_CMD_UPDATE_BOTH,
164 pcmk__str_null_matches);
165
166
167 a = g_hash_table_lookup(attributes, attr);
168 if (a == NULL) {
169 if (update_both || pcmk__str_eq(op, PCMK__ATTRD_CMD_UPDATE, pcmk__str_none)) {
170 a = attrd_create_attribute(xml);
171 } else {
172 crm_warn("Could not update %s: attribute not found", attr);
173 return NULL;
174 }
175 }
176
177
178 if (update_both || pcmk__str_eq(op, PCMK__ATTRD_CMD_UPDATE_DELAY, pcmk__str_none)) {
179 int rc = attrd_update_dampening(a, xml, attr);
180
181 if (rc != pcmk_rc_ok || !update_both) {
182 return NULL;
183 }
184 }
185
186 return a;
187 }