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

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