This source file includes following definitions.
- attrd_create_attribute
- attrd_update_dampening
- attrd_add_value_xml
- attrd_clear_value_seen
- attrd_populate_attribute
- attrd_set_id
- attrd_nvpair_id
   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/common/logging.h>
  18 #include <crm/common/results.h>
  19 #include <crm/common/strings_internal.h>
  20 #include <crm/common/xml.h>
  21 
  22 #include "pacemaker-attrd.h"
  23 
  24 static attribute_t *
  25 attrd_create_attribute(xmlNode *xml)
     
  26 {
  27     int is_private = 0;
  28     long long dampen = 0;
  29     const char *name = crm_element_value(xml, PCMK__XA_ATTR_NAME);
  30     const char *set_type = crm_element_value(xml, PCMK__XA_ATTR_SET_TYPE);
  31     const char *dampen_s = crm_element_value(xml, PCMK__XA_ATTR_DAMPENING);
  32     attribute_t *a = NULL;
  33 
  34     if (set_type == NULL) {
  35         set_type = PCMK_XE_INSTANCE_ATTRIBUTES;
  36     }
  37 
  38     
  39 
  40 
  41     crm_element_value_int(xml, PCMK__XA_ATTR_IS_PRIVATE, &is_private);
  42     if (!is_private && !pcmk__str_any_of(set_type,
  43                                          PCMK_XE_INSTANCE_ATTRIBUTES,
  44                                          PCMK_XE_UTILIZATION, NULL)) {
  45         crm_warn("Ignoring attribute %s with invalid set type %s",
  46                  pcmk__s(name, "(unidentified)"), set_type);
  47         return NULL;
  48     }
  49 
  50     a = pcmk__assert_alloc(1, sizeof(attribute_t));
  51 
  52     a->id = pcmk__str_copy(name);
  53     a->set_type = pcmk__str_copy(set_type);
  54     a->set_id = crm_element_value_copy(xml, PCMK__XA_ATTR_SET);
  55     a->user = crm_element_value_copy(xml, PCMK__XA_ATTR_USER);
  56     a->values = pcmk__strikey_table(NULL, attrd_free_attribute_value);
  57 
  58     if (is_private) {
  59         attrd_set_attr_flags(a, attrd_attr_is_private);
  60     }
  61 
  62     if (dampen_s != NULL) {
  63         dampen = crm_get_msec(dampen_s);
  64     }
  65 
  66     if (dampen > 0) {
  67         a->timeout_ms = (int) QB_MIN(dampen, INT_MAX);
  68         a->timer = attrd_add_timer(a->id, a->timeout_ms, a);
  69     } else if (dampen < 0) {
  70         crm_warn("Ignoring invalid delay %s for attribute %s", dampen_s, a->id);
  71     }
  72 
  73     crm_trace("Created attribute %s with %s write delay and %s CIB user",
  74               a->id,
  75               ((dampen > 0)? pcmk__readable_interval(a->timeout_ms) : "no"),
  76               pcmk__s(a->user, "default"));
  77 
  78     g_hash_table_replace(attributes, a->id, a);
  79     return a;
  80 }
  81 
  82 static int
  83 attrd_update_dampening(attribute_t *a, xmlNode *xml, const char *attr)
     
  84 {
  85     const char *dvalue = crm_element_value(xml, PCMK__XA_ATTR_DAMPENING);
  86     long long dampen = 0;
  87 
  88     if (dvalue == NULL) {
  89         crm_warn("Could not update %s: peer did not specify value for delay",
  90                  attr);
  91         return EINVAL;
  92     }
  93 
  94     dampen = crm_get_msec(dvalue);
  95     if (dampen < 0) {
  96         crm_warn("Could not update %s: invalid delay value %dms (%s)",
  97                  attr, dampen, dvalue);
  98         return EINVAL;
  99     }
 100 
 101     if (a->timeout_ms != dampen) {
 102         mainloop_timer_del(a->timer);
 103         a->timeout_ms = (int) QB_MIN(dampen, INT_MAX);
 104         if (dampen > 0) {
 105             a->timer = attrd_add_timer(attr, a->timeout_ms, a);
 106             crm_info("Update attribute %s delay to %dms (%s)",
 107                      attr, dampen, dvalue);
 108         } else {
 109             a->timer = NULL;
 110             crm_info("Update attribute %s to remove delay", attr);
 111         }
 112 
 113         
 114 
 115 
 116         attrd_write_or_elect_attribute(a);
 117     }
 118 
 119     return pcmk_rc_ok;
 120 }
 121 
 122 GHashTable *attributes = NULL;
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 
 132 
 133 
 134 
 135 xmlNode *
 136 attrd_add_value_xml(xmlNode *parent, const attribute_t *a,
     
 137                     const attribute_value_t *v, bool force_write)
 138 {
 139     xmlNode *xml = pcmk__xe_create(parent, __func__);
 140 
 141     crm_xml_add(xml, PCMK__XA_ATTR_NAME, a->id);
 142     crm_xml_add(xml, PCMK__XA_ATTR_SET_TYPE, a->set_type);
 143     crm_xml_add(xml, PCMK__XA_ATTR_SET, a->set_id);
 144     crm_xml_add(xml, PCMK__XA_ATTR_USER, a->user);
 145     pcmk__xe_add_node(xml, v->nodename, v->nodeid);
 146     if (pcmk_is_set(v->flags, attrd_value_remote)) {
 147         crm_xml_add_int(xml, PCMK__XA_ATTR_IS_REMOTE, 1);
 148     }
 149     crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current);
 150     crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, a->timeout_ms / 1000);
 151     crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE,
 152                     pcmk_is_set(a->flags, attrd_attr_is_private));
 153     crm_xml_add_int(xml, PCMK__XA_ATTRD_IS_FORCE_WRITE, force_write);
 154 
 155     return xml;
 156 }
 157 
 158 void
 159 attrd_clear_value_seen(void)
     
 160 {
 161     GHashTableIter aIter;
 162     GHashTableIter vIter;
 163     attribute_t *a;
 164     attribute_value_t *v = NULL;
 165 
 166     g_hash_table_iter_init(&aIter, attributes);
 167     while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
 168         g_hash_table_iter_init(&vIter, a->values);
 169         while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & v)) {
 170             attrd_clear_value_flags(v, attrd_value_from_peer);
 171         }
 172     }
 173 }
 174 
 175 attribute_t *
 176 attrd_populate_attribute(xmlNode *xml, const char *attr)
     
 177 {
 178     attribute_t *a = NULL;
 179     bool update_both = false;
 180 
 181     const char *op = crm_element_value(xml, PCMK_XA_TASK);
 182 
 183     
 184     update_both = pcmk__str_eq(op, PCMK__ATTRD_CMD_UPDATE_BOTH,
 185                                pcmk__str_null_matches);
 186 
 187     
 188     a = g_hash_table_lookup(attributes, attr);
 189     if (a == NULL) {
 190         if (update_both || pcmk__str_eq(op, PCMK__ATTRD_CMD_UPDATE, pcmk__str_none)) {
 191             a = attrd_create_attribute(xml);
 192             if (a == NULL) {
 193                 return NULL;
 194             }
 195 
 196         } else {
 197             crm_warn("Could not update %s: attribute not found", attr);
 198             return NULL;
 199         }
 200     }
 201 
 202     
 203     if (update_both || pcmk__str_eq(op, PCMK__ATTRD_CMD_UPDATE_DELAY, pcmk__str_none)) {
 204         int rc = attrd_update_dampening(a, xml, attr);
 205 
 206         if (rc != pcmk_rc_ok || !update_both) {
 207             return NULL;
 208         }
 209     }
 210 
 211     return a;
 212 }
 213 
 214 
 215 
 216 
 217 
 218 
 219 
 220 
 221 
 222 
 223 char *
 224 attrd_set_id(const attribute_t *attr, const char *node_state_id)
     
 225 {
 226     char *set_id = NULL;
 227 
 228     CRM_ASSERT((attr != NULL) && (node_state_id != NULL));
 229 
 230     if (attr->set_id == NULL) {
 231         
 232 
 233 
 234 
 235 
 236 
 237         set_id = crm_strdup_printf("%s-%s", PCMK_XE_STATUS, node_state_id);
 238     } else {
 239         
 240 
 241 
 242 
 243 
 244 
 245 
 246         set_id = pcmk__str_copy(attr->set_id);
 247     }
 248     crm_xml_sanitize_id(set_id);
 249     return set_id;
 250 }
 251 
 252 
 253 
 254 
 255 
 256 
 257 
 258 
 259 
 260 
 261 char *
 262 attrd_nvpair_id(const attribute_t *attr, const char *node_state_id)
     
 263 {
 264     char *nvpair_id = NULL;
 265 
 266     if (attr->set_id != NULL) {
 267         nvpair_id = crm_strdup_printf("%s-%s", attr->set_id, attr->id);
 268 
 269     } else {
 270         nvpair_id = crm_strdup_printf(PCMK_XE_STATUS "-%s-%s",
 271                                       node_state_id, attr->id);
 272     }
 273     crm_xml_sanitize_id(nvpair_id);
 274     return nvpair_id;
 275 }