root/daemons/based/cibmon.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main
  2. usage
  3. cib_connection_destroy
  4. cibmon_diff
  5. cibmon_shutdown

   1 /*
   2  * Copyright 2004-2020 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 General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <sys/param.h>
  13 
  14 #include <crm/crm.h>
  15 
  16 #include <stdio.h>
  17 #include <sys/types.h>
  18 #include <unistd.h>
  19 
  20 #include <stdlib.h>
  21 #include <errno.h>
  22 #include <fcntl.h>
  23 
  24 #include <crm/msg_xml.h>
  25 #include <crm/common/xml.h>
  26 #include <crm/common/mainloop.h>
  27 #include <crm/cib/internal.h>
  28 
  29 #include <crm/common/ipc.h>
  30 #include <crm/pengine/status.h>
  31 
  32 #include <crm/cib.h>
  33 
  34 #ifdef HAVE_GETOPT_H
  35 #  include <getopt.h>
  36 #endif
  37 
  38 static int max_failures = 30;
  39 
  40 static gboolean log_diffs = FALSE;
  41 static gboolean log_updates = FALSE;
  42 
  43 static GMainLoop *mainloop = NULL;
  44 void usage(const char *cmd, crm_exit_t exit_status);
  45 void cib_connection_destroy(gpointer user_data);
  46 
  47 void cibmon_shutdown(int nsig);
  48 void cibmon_diff(const char *event, xmlNode * msg);
  49 
  50 static cib_t *cib = NULL;
  51 static xmlNode *cib_copy = NULL;
  52 
  53 #define OPTARGS "V?m:du"
  54 
  55 int
  56 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58     int argerr = 0;
  59     int flag;
  60     int attempts = 0;
  61     int rc = pcmk_ok;
  62 
  63 #ifdef HAVE_GETOPT_H
  64     int option_index = 0;
  65 
  66     static struct option long_options[] = {
  67         /* Top-level Options */
  68         {"verbose", 0, 0, 'V'},
  69         {"help", 0, 0, '?'},
  70         {"log-diffs", 0, 0, 'd'},
  71         {"log-updates", 0, 0, 'u'},
  72         {"max-conn-fail", 1, 0, 'm'},
  73         {0, 0, 0, 0}
  74     };
  75 #endif
  76 
  77     crm_log_cli_init("cibmon");
  78 
  79     crm_signal_handler(SIGTERM, cibmon_shutdown);
  80 
  81     while (1) {
  82 #ifdef HAVE_GETOPT_H
  83         flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index);
  84 #else
  85         flag = getopt(argc, argv, OPTARGS);
  86 #endif
  87         if (flag == -1)
  88             break;
  89 
  90         switch (flag) {
  91             case 'V':
  92                 crm_bump_log_level(argc, argv);
  93                 break;
  94             case '?':
  95                 usage(crm_system_name, CRM_EX_OK);
  96                 break;
  97             case 'd':
  98                 log_diffs = TRUE;
  99                 break;
 100             case 'u':
 101                 log_updates = TRUE;
 102                 break;
 103             case 'm':
 104                 max_failures = crm_parse_int(optarg, "30");
 105                 break;
 106             default:
 107                 printf("Argument code 0%o (%c)" " is not (?yet?) supported\n", flag, flag);
 108                 ++argerr;
 109                 break;
 110         }
 111     }
 112 
 113     if (optind < argc) {
 114         printf("non-option ARGV-elements: ");
 115         while (optind < argc)
 116             printf("%s ", argv[optind++]);
 117         printf("\n");
 118     }
 119 
 120     if (optind > argc) {
 121         ++argerr;
 122     }
 123 
 124     if (argerr) {
 125         usage(crm_system_name, CRM_EX_USAGE);
 126     }
 127 
 128     cib = cib_new();
 129 
 130     do {
 131         sleep(1);
 132         rc = cib->cmds->signon(cib, crm_system_name, cib_query);
 133 
 134     } while (rc == -ENOTCONN && attempts++ < max_failures);
 135 
 136     if (rc != pcmk_ok) {
 137         crm_err("Signon to CIB failed: %s", pcmk_strerror(rc));
 138         goto fail;
 139     }
 140 
 141     crm_debug("Setting dnotify");
 142     rc = cib->cmds->set_connection_dnotify(cib, cib_connection_destroy);
 143     if (rc != pcmk_ok) {
 144         crm_err("Failed to set dnotify callback: %s", pcmk_strerror(rc));
 145         goto fail;
 146     }
 147 
 148     crm_debug("Setting diff callback");
 149     rc = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, cibmon_diff);
 150     if (rc != pcmk_ok) {
 151         crm_err("Failed to set diff callback: %s", pcmk_strerror(rc));
 152         goto fail;
 153     }
 154 
 155     mainloop = g_main_loop_new(NULL, FALSE);
 156     crm_info("Starting mainloop");
 157     g_main_loop_run(mainloop);
 158     crm_trace("%s exiting normally", crm_system_name);
 159     fflush(stderr);
 160     return CRM_EX_OK;
 161 
 162 fail:
 163     crm_err("Setup failed, could not monitor CIB actions");
 164     return CRM_EX_ERROR;
 165 }
 166 
 167 void
 168 usage(const char *cmd, crm_exit_t exit_status)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170     FILE *stream;
 171 
 172     stream = (exit_status == CRM_EX_OK)? stdout : stderr;
 173     fflush(stream);
 174 
 175     crm_exit(exit_status);
 176 }
 177 
 178 void
 179 cib_connection_destroy(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181     cib_t *conn = user_data;
 182 
 183     crm_err("Connection to the CIB terminated... exiting");
 184     conn->cmds->signoff(conn);  /* Ensure IPC is cleaned up */
 185     g_main_loop_quit(mainloop);
 186     return;
 187 }
 188 
 189 void
 190 cibmon_diff(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192     int rc = -1;
 193     const char *op = NULL;
 194     unsigned int log_level = LOG_INFO;
 195 
 196     xmlNode *diff = NULL;
 197     xmlNode *cib_last = NULL;
 198     xmlNode *update = get_message_xml(msg, F_CIB_UPDATE);
 199 
 200     if (msg == NULL) {
 201         crm_err("NULL update");
 202         return;
 203     }
 204 
 205     crm_element_value_int(msg, F_CIB_RC, &rc);
 206     op = crm_element_value(msg, F_CIB_OPERATION);
 207     diff = get_message_xml(msg, F_CIB_UPDATE_RESULT);
 208 
 209     if (rc < pcmk_ok) {
 210         log_level = LOG_WARNING;
 211         do_crm_log(log_level, "[%s] %s ABORTED: %s", event, op, pcmk_strerror(rc));
 212         return;
 213     }
 214 
 215     if (log_diffs) {
 216         xml_log_patchset(log_level, op, diff);
 217     }
 218 
 219     if (log_updates && update != NULL) {
 220         crm_log_xml_trace(update, "raw_update");
 221     }
 222 
 223     if (cib_copy != NULL) {
 224         cib_last = cib_copy;
 225         cib_copy = NULL;
 226         rc = cib_process_diff(op, cib_force_diff, NULL, NULL, diff, cib_last, &cib_copy, NULL);
 227 
 228         if (rc != pcmk_ok) {
 229             crm_debug("Update didn't apply, requesting full copy: %s", pcmk_strerror(rc));
 230             free_xml(cib_copy);
 231             cib_copy = NULL;
 232         }
 233     }
 234 
 235     if (cib_copy == NULL) {
 236         rc = cib->cmds->query(cib, NULL, &cib_copy, cib_scope_local | cib_sync_call);
 237     }
 238 
 239     if(rc == -EACCES) {
 240         crm_exit(CRM_EX_INSUFFICIENT_PRIV);
 241     }
 242 
 243     free_xml(cib_last);
 244 }
 245 
 246 void
 247 cibmon_shutdown(int nsig)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249     crm_exit(CRM_EX_OK);
 250 }

/* [previous][next][first][last][top][bottom][index][help] */