This source file includes following definitions.
- main
- usage
- cib_connection_destroy
- cibmon_diff
- cibmon_shutdown
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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)
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
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)
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)
189 {
190 cib_t *conn = user_data;
191
192 crm_err("Connection to the CIB terminated... exiting");
193 conn->cmds->signoff(conn);
194 g_main_quit(mainloop);
195 return;
196 }
197
198 void
199 cibmon_diff(const char *event, xmlNode * msg)
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)
257 {
258 crm_exit(pcmk_ok);
259 }