This source file includes following definitions.
- attrd_shutting_down
- attrd_shutdown
- attrd_init_mainloop
- attrd_run_mainloop
- attrd_ipc_accept
- attrd_ipc_closed
- attrd_ipc_destroy
- attrd_init_ipc
- attrd_cib_disconnect
- attrd_cib_replaced_cb
- attrd_value_needs_expansion
- attrd_expand_value
- attrd_failure_regex
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <stdio.h>
  13 #include <stdbool.h>
  14 #include <errno.h>
  15 #include <glib.h>
  16 #include <regex.h>
  17 #include <sys/types.h>
  18 
  19 #include <crm/crm.h>
  20 #include <crm/common/ipc_internal.h>
  21 #include <crm/common/mainloop.h>
  22 
  23 #include "pacemaker-attrd.h"
  24 
  25 cib_t *the_cib = NULL;
  26 
  27 static bool shutting_down = FALSE;
  28 static GMainLoop *mloop = NULL;
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 gboolean
  37 attrd_shutting_down()
     
  38 {
  39     return shutting_down;
  40 }
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 void
  49 attrd_shutdown(int nsig)
     
  50 {
  51     
  52     shutting_down = TRUE;
  53 
  54     
  55     mainloop_destroy_signal(SIGTERM);
  56     mainloop_destroy_signal(SIGCHLD);
  57     mainloop_destroy_signal(SIGPIPE);
  58     mainloop_destroy_signal(SIGUSR1);
  59     mainloop_destroy_signal(SIGUSR2);
  60     mainloop_destroy_signal(SIGTRAP);
  61 
  62     if ((mloop == NULL) || !g_main_loop_is_running(mloop)) {
  63         
  64 
  65 
  66         crm_exit(CRM_EX_OK);
  67     } else {
  68         g_main_loop_quit(mloop);
  69         g_main_loop_unref(mloop);
  70     }
  71 }
  72 
  73 
  74 
  75 
  76 
  77 void
  78 attrd_init_mainloop()
     
  79 {
  80     mloop = g_main_loop_new(NULL, FALSE);
  81 }
  82 
  83 
  84 
  85 
  86 
  87 void
  88 attrd_run_mainloop()
     
  89 {
  90     g_main_loop_run(mloop);
  91 }
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 static int32_t
 104 attrd_ipc_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
     
 105 {
 106     crm_trace("New client connection %p", c);
 107     if (shutting_down) {
 108         crm_info("Ignoring new connection from pid %d during shutdown",
 109                  pcmk__client_pid(c));
 110         return -EPERM;
 111     }
 112 
 113     if (pcmk__new_client(c, uid, gid) == NULL) {
 114         return -EIO;
 115     }
 116     return pcmk_ok;
 117 }
 118 
 119 
 120 
 121 
 122 
 123 
 124 
 125 
 126 
 127 static int32_t
 128 attrd_ipc_closed(qb_ipcs_connection_t *c)
     
 129 {
 130     pcmk__client_t *client = pcmk__find_client(c);
 131 
 132     if (client == NULL) {
 133         crm_trace("Ignoring request to clean up unknown connection %p", c);
 134     } else {
 135         crm_trace("Cleaning up closed client connection %p", c);
 136         pcmk__free_client(client);
 137     }
 138     return FALSE;
 139 }
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 
 148 
 149 
 150 static void
 151 attrd_ipc_destroy(qb_ipcs_connection_t *c)
     
 152 {
 153     crm_trace("Destroying client connection %p", c);
 154     attrd_ipc_closed(c);
 155 }
 156 
 157 
 158 
 159 
 160 
 161 
 162 
 163 
 164 void
 165 attrd_init_ipc(qb_ipcs_service_t **ipcs, qb_ipcs_msg_process_fn dispatch_fn)
     
 166 {
 167 
 168     static struct qb_ipcs_service_handlers ipc_callbacks = {
 169         .connection_accept = attrd_ipc_accept,
 170         .connection_created = NULL,
 171         .msg_process = NULL,
 172         .connection_closed = attrd_ipc_closed,
 173         .connection_destroyed = attrd_ipc_destroy
 174     };
 175 
 176     ipc_callbacks.msg_process = dispatch_fn;
 177     pcmk__serve_attrd_ipc(ipcs, &ipc_callbacks);
 178 }
 179 
 180 void
 181 attrd_cib_disconnect()
     
 182 {
 183     CRM_CHECK(the_cib != NULL, return);
 184     the_cib->cmds->del_notify_callback(the_cib, T_CIB_REPLACE_NOTIFY, attrd_cib_replaced_cb);
 185     the_cib->cmds->del_notify_callback(the_cib, T_CIB_DIFF_NOTIFY, attrd_cib_updated_cb); 
 186     the_cib->cmds->signoff(the_cib);
 187     cib_delete(the_cib);
 188     the_cib = NULL;
 189 }
 190 
 191 void
 192 attrd_cib_replaced_cb(const char *event, xmlNode * msg)
     
 193 {
 194     if (attrd_shutting_down()) {
 195         return;
 196     }
 197 
 198     if (attrd_election_won()) {
 199         crm_notice("Updating all attributes after %s event", event);
 200         write_attributes(TRUE, FALSE);
 201     }
 202 
 203     
 204     mainloop_set_trigger(attrd_config_read);
 205 }
 206 
 207 
 208 #define plus_plus_len (5)
 209 
 210 
 211 
 212 
 213 
 214 
 215 
 216 
 217 
 218 gboolean
 219 attrd_value_needs_expansion(const char *value)
     
 220 {
 221     return ((strlen(value) >= (plus_plus_len + 2))
 222            && (value[plus_plus_len] == '+')
 223            && ((value[plus_plus_len + 1] == '+')
 224                || (value[plus_plus_len + 1] == '=')));
 225 }
 226 
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234 
 235 
 236 int
 237 attrd_expand_value(const char *value, const char *old_value)
     
 238 {
 239     int offset = 1;
 240     int int_value = char2score(old_value);
 241 
 242     if (value[plus_plus_len + 1] != '+') {
 243         const char *offset_s = value + (plus_plus_len + 2);
 244 
 245         offset = char2score(offset_s);
 246     }
 247     int_value += offset;
 248 
 249     if (int_value > INFINITY) {
 250         int_value = INFINITY;
 251     }
 252     return int_value;
 253 }
 254 
 255 
 256 
 257 
 258 
 259 
 260 
 261 
 262 
 263 
 264 
 265 
 266 
 267 
 268 int
 269 attrd_failure_regex(regex_t *regex, const char *rsc, const char *op,
     
 270                     guint interval_ms)
 271 {
 272     char *pattern = NULL;
 273     int rc;
 274 
 275     
 276 
 277     if (rsc == NULL) {
 278         pattern = strdup(ATTRD_RE_CLEAR_ALL);
 279     } else if (op == NULL) {
 280         pattern = crm_strdup_printf(ATTRD_RE_CLEAR_ONE, rsc);
 281     } else {
 282         pattern = crm_strdup_printf(ATTRD_RE_CLEAR_OP, rsc, op, interval_ms);
 283     }
 284 
 285     
 286     crm_trace("Clearing attributes matching %s", pattern);
 287     rc = regcomp(regex, pattern, REG_EXTENDED|REG_NOSUB);
 288     free(pattern);
 289 
 290     return (rc == 0)? pcmk_ok : -EINVAL;
 291 }