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