Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/crmd/Makefile.am b/crmd/Makefile.am
index f0addfc643..0eab529514 100644
--- a/crmd/Makefile.am
+++ b/crmd/Makefile.am
@@ -1,57 +1,57 @@
#
# Copyright (C) 2004 Andrew Beekhof
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
include $(top_srcdir)/Makefile.common
halibdir = $(CRM_DAEMON_DIR)
## binary progs
halib_PROGRAMS = crmd
## SOURCES
noinst_HEADERS = crmd.h crmd_fsa.h crmd_messages.h fsa_defines.h \
fsa_matrix.h fsa_proto.h crmd_utils.h crmd_callbacks.h \
crmd_lrm.h te_callbacks.h tengine.h
crmd_CFLAGS = $(CFLAGS_HARDENED_EXE)
crmd_LDFLAGS = $(LDFLAGS_HARDENED_EXE)
crmd_LDADD = $(top_builddir)/lib/fencing/libstonithd.la \
$(top_builddir)/lib/transition/libtransitioner.la \
$(top_builddir)/lib/pengine/libpe_rules.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/cluster/libcrmcluster.la \
$(top_builddir)/lib/common/libcrmcommon.la \
$(top_builddir)/lib/services/libcrmservice.la \
$(top_builddir)/lib/lrmd/liblrmd.la \
$(CLUSTERLIBS)
-crmd_SOURCES = main.c crmd.c corosync.c notify.c \
+crmd_SOURCES = main.c crmd.c corosync.c crmd_alerts.c \
fsa.c control.c messages.c membership.c callbacks.c attrd.c \
election.c join_client.c join_dc.c subsystems.c throttle.c \
cib.c pengine.c tengine.c lrm.c lrm_state.c remote_lrmd_ra.c \
utils.c misc.c te_events.c te_actions.c te_utils.c te_callbacks.c
if BUILD_HEARTBEAT_SUPPORT
crmd_SOURCES += heartbeat.c
endif
if BUILD_XML_HELP
man7_MANS = crmd.7
endif
CLEANFILES = $(man7_MANS)
diff --git a/crmd/notify.c b/crmd/crmd_alerts.c
similarity index 99%
rename from crmd/notify.c
rename to crmd/crmd_alerts.c
index 40b34b4410..c66cbac2bb 100644
--- a/crmd/notify.c
+++ b/crmd/crmd_alerts.c
@@ -1,381 +1,381 @@
/*
* Copyright (C) 2015 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <crm_internal.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/pengine/rules.h>
-#include "notify.h"
+#include "crmd_alerts.h"
#include "crmd_messages.h"
#include <crm/common/alerts_internal.h>
#include <crm/common/iso8601_internal.h>
static char *notify_script = NULL;
static char *notify_target = NULL;
static int alerts_inflight = 0;
static gboolean draining_alerts = FALSE;
/*
* syncronize local data with cib
*/
static GHashTable *
get_meta_attrs_from_cib(xmlNode *basenode, crm_alert_entry_t *entry,
guint *max_timeout)
{
GHashTable *config_hash =
g_hash_table_new_full(crm_str_hash, g_str_equal,
g_hash_destroy_str, g_hash_destroy_str);
crm_time_t *now = crm_time_new(NULL);
const char *value = NULL;
unpack_instance_attributes(basenode, basenode, XML_TAG_META_SETS, NULL,
config_hash, NULL, FALSE, now);
value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TIMEOUT);
if (value) {
entry->timeout = crm_get_msec(value);
if (entry->timeout <= 0) {
if (entry->timeout == 0) {
crm_trace("Setting timeout to default %dmsec",
CRM_ALERT_DEFAULT_TIMEOUT_MS);
} else {
crm_warn("Invalid timeout value setting to default %dmsec",
CRM_ALERT_DEFAULT_TIMEOUT_MS);
}
entry->timeout = CRM_ALERT_DEFAULT_TIMEOUT_MS;
} else {
crm_trace("Found timeout %dmsec", entry->timeout);
}
if (entry->timeout > *max_timeout) {
*max_timeout = entry->timeout;
}
}
value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TSTAMP_FORMAT);
if (value) {
/* hard to do any checks here as merely anything can
* can be a valid time-format-string
*/
entry->tstamp_format = (char *) value;
crm_trace("Found timestamp format string '%s'", value);
}
crm_time_free(now);
return config_hash; /* keep hash as long as strings are needed */
}
void
parse_notifications(xmlNode *notifications)
{
xmlNode *notify;
crm_alert_entry_t entry;
guint max_timeout = 0;
crm_free_notify_list();
crm_alert_max_alert_timeout = CRM_ALERT_DEFAULT_TIMEOUT_MS;
if (notifications) {
crm_info("We have an alerts section in the cib");
if (notify_script) {
crm_warn("Cib contains configuration for Legacy Notifications "
"which is overruled by alerts section");
}
} else {
crm_info("No optional alerts section in cib");
if (notify_script) {
entry = (crm_alert_entry_t) {
.id = (char *) "legacy_notification",
.path = notify_script,
.timeout = CRM_ALERT_DEFAULT_TIMEOUT_MS,
.recipient = notify_target
};
crm_add_dup_notify_list_entry(&entry);
crm_info("Legacy Notifications enabled");
}
return;
}
for (notify = first_named_child(notifications, XML_CIB_TAG_ALERT);
notify; notify = __xml_next(notify)) {
xmlNode *recipient;
int recipients = 0, envvars = 0;
GHashTable *config_hash = NULL;
entry = (crm_alert_entry_t) {
.id = (char *) crm_element_value(notify, XML_ATTR_ID),
.path = (char *) crm_element_value(notify, XML_ALERT_ATTR_PATH),
.timeout = CRM_ALERT_DEFAULT_TIMEOUT_MS,
.tstamp_format = (char *) CRM_ALERT_DEFAULT_TSTAMP_FORMAT
};
entry.envvars =
crm_get_envvars_from_cib(notify,
entry.envvars,
&envvars);
config_hash =
get_meta_attrs_from_cib(notify, &entry, &max_timeout);
crm_debug("Found alert: id=%s, path=%s, timeout=%d, "
"tstamp_format=%s, %d additional environment variables",
entry.id, entry.path, entry.timeout,
entry.tstamp_format, envvars);
for (recipient = first_named_child(notify,
XML_CIB_TAG_ALERT_RECIPIENT);
recipient; recipient = __xml_next(recipient)) {
int envvars_added = 0;
entry.recipient = (char *) crm_element_value(recipient,
XML_ALERT_ATTR_REC_VALUE);
recipients++;
entry.envvars =
crm_get_envvars_from_cib(recipient,
entry.envvars,
&envvars_added);
{
crm_alert_entry_t recipient_entry = entry;
GHashTable *config_hash =
get_meta_attrs_from_cib(recipient,
&recipient_entry,
&max_timeout);
crm_add_dup_notify_list_entry(&recipient_entry);
crm_debug("Alert has recipient: id=%s, value=%s, "
"%d additional environment variables",
crm_element_value(recipient, XML_ATTR_ID),
recipient_entry.recipient, envvars_added);
g_hash_table_destroy(config_hash);
}
entry.envvars =
crm_drop_envvars(entry.envvars, envvars_added);
}
if (recipients == 0) {
crm_add_dup_notify_list_entry(&entry);
}
crm_drop_envvars(entry.envvars, -1);
g_hash_table_destroy(config_hash);
}
if (max_timeout > 0) {
crm_alert_max_alert_timeout = max_timeout;
}
}
/*
* end of synchronization of local data with cib
*/
void
crmd_enable_notifications(const char *script, const char *target)
{
free(notify_script);
notify_script = ((script) &&
(strcmp(script,"/dev/null")))?strdup(script):NULL;
free(notify_target);
notify_target = (target != NULL)?strdup(target):NULL;
}
static void
crmd_notify_complete(svc_action_t *op)
{
alerts_inflight--;
if(op->rc == 0) {
crm_info("Alert %d (%s) complete", op->sequence, op->agent);
} else {
crm_warn("Alert %d (%s) failed: %d", op->sequence, op->agent,
op->rc);
}
}
static void
send_notifications(const char *kind)
{
svc_action_t *notify = NULL;
static int operations = 0;
GListPtr l;
crm_time_hr_t *now = crm_time_hr_new(NULL);
crm_set_alert_key(CRM_alert_kind, kind);
crm_set_alert_key(CRM_alert_version, VERSION);
for (l = g_list_first(crm_alert_list); l; l = g_list_next(l)) {
crm_alert_entry_t *entry = (crm_alert_entry_t *)(l->data);
char *timestamp = crm_time_format_hr(entry->tstamp_format, now);
operations++;
if (!draining_alerts) {
crm_debug("Sending '%s' alert to '%s' via '%s'", kind,
entry->recipient, entry->path);
crm_set_alert_key(CRM_alert_recipient, entry->recipient);
crm_set_alert_key_int(CRM_alert_node_sequence, operations);
crm_set_alert_key(CRM_alert_timestamp, timestamp);
notify = services_action_create_generic(entry->path, NULL);
notify->timeout = entry->timeout;
notify->standard = strdup("event");
notify->id = strdup(entry->id);
notify->agent = strdup(entry->path);
notify->sequence = operations;
crm_set_envvar_list(entry->envvars);
alerts_inflight++;
if(services_action_async(notify, &crmd_notify_complete) == FALSE) {
services_action_free(notify);
alerts_inflight--;
}
crm_unset_envvar_list(entry->envvars);
} else {
crm_warn("Ignoring '%s' alert to '%s' via '%s' received "
"while shutting down",
kind, entry->recipient, entry->path);
}
free(timestamp);
}
crm_unset_alert_keys();
if (now) {
free(now);
}
}
void
crmd_notify_node_event(crm_node_t *node)
{
if(!crm_alert_list) {
return;
}
crm_set_alert_key(CRM_alert_node, node->uname);
crm_set_alert_key_int(CRM_alert_nodeid, node->id);
crm_set_alert_key(CRM_alert_desc, node->state);
send_notifications("node");
}
void
crmd_notify_fencing_op(stonith_event_t * e)
{
char *desc = NULL;
if (!crm_alert_list) {
return;
}
desc = crm_strdup_printf(
"Operation %s of %s by %s for %s@%s: %s (ref=%s)",
e->action, e->target, e->executioner ? e->executioner : "<no-one>",
e->client_origin, e->origin, pcmk_strerror(e->result), e->id);
crm_set_alert_key(CRM_alert_node, e->target);
crm_set_alert_key(CRM_alert_task, e->operation);
crm_set_alert_key(CRM_alert_desc, desc);
crm_set_alert_key_int(CRM_alert_rc, e->result);
send_notifications("fencing");
free(desc);
}
void
crmd_notify_resource_op(const char *node, lrmd_event_data_t * op)
{
int target_rc = 0;
if(!crm_alert_list) {
return;
}
target_rc = rsc_op_expected_rc(op);
if(op->interval == 0 && target_rc == op->rc &&
safe_str_eq(op->op_type, RSC_STATUS)) {
/* Leave it up to the script if they want to notify for
* 'failed' probes, only swallow ones for which the result was
* unexpected.
*
* Even if we find a resource running, it was probably because
* someone erased the status section.
*/
return;
}
crm_set_alert_key(CRM_alert_node, node);
crm_set_alert_key(CRM_alert_rsc, op->rsc_id);
crm_set_alert_key(CRM_alert_task, op->op_type);
crm_set_alert_key_int(CRM_alert_interval, op->interval);
crm_set_alert_key_int(CRM_alert_target_rc, target_rc);
crm_set_alert_key_int(CRM_alert_status, op->op_status);
crm_set_alert_key_int(CRM_alert_rc, op->rc);
if(op->op_status == PCMK_LRM_OP_DONE) {
crm_set_alert_key(CRM_alert_desc, services_ocf_exitcode_str(op->rc));
} else {
crm_set_alert_key(CRM_alert_desc, services_lrm_status_str(op->op_status));
}
send_notifications("resource");
}
static gboolean
alert_drain_timeout_callback(gpointer user_data)
{
gboolean *timeout_popped = (gboolean *) user_data;
*timeout_popped = TRUE;
return FALSE;
}
void
crmd_drain_alerts(GMainContext *ctx)
{
guint timer;
gboolean timeout_popped = FALSE;
draining_alerts = TRUE;
timer = g_timeout_add(crm_alert_max_alert_timeout + 5000,
alert_drain_timeout_callback,
(gpointer) &timeout_popped);
while(alerts_inflight && !timeout_popped) {
crm_trace("Draining mainloop while still %d alerts are in flight (timeout=%dms)",
alerts_inflight, crm_alert_max_alert_timeout + 5000);
g_main_context_iteration(ctx, TRUE);
}
if (!timeout_popped && (timer > 0)) {
g_source_remove(timer);
}
}
diff --git a/crmd/notify.h b/crmd/crmd_alerts.h
similarity index 96%
rename from crmd/notify.h
rename to crmd/crmd_alerts.h
index 63beed7629..b8f3a81aa6 100644
--- a/crmd/notify.h
+++ b/crmd/crmd_alerts.h
@@ -1,32 +1,32 @@
/*
* Copyright (C) 2015 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef CRMD_NOTIFY__H
-# define CRMD_NOTIFY__H
+#ifndef CRMD_ALERT__H
+# define CRMD_ALERT__H
# include <crm/crm.h>
# include <crm/cluster.h>
# include <crm/stonith-ng.h>
void crmd_enable_notifications(const char *script, const char *target);
void crmd_notify_node_event(crm_node_t *node);
void crmd_notify_fencing_op(stonith_event_t *e);
void crmd_notify_resource_op(const char *node, lrmd_event_data_t *op);
void crmd_drain_alerts(GMainContext *ctx);
void parse_notifications(xmlNode *notifications);
#endif
diff --git a/crmd/crmd_utils.h b/crmd/crmd_utils.h
index 5fe34ba893..1acba01f38 100644
--- a/crmd/crmd_utils.h
+++ b/crmd/crmd_utils.h
@@ -1,134 +1,134 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CRMD_UTILS__H
# define CRMD_UTILS__H
# include <crm/crm.h>
# include <crm/common/xml.h>
# include <crm/cib/internal.h> /* For CIB_OP_MODIFY */
-# include "notify.h"
+# include "crmd_alerts.h"
# define CLIENT_EXIT_WAIT 30
# define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# define fsa_cib_delete(section, data, options, call_id, user_name) \
if(fsa_cib_conn != NULL) { \
call_id = cib_internal_op( \
fsa_cib_conn, CIB_OP_DELETE, NULL, section, data, \
NULL, options, user_name); \
\
} else { \
crm_err("No CIB connection available"); \
}
# define fsa_cib_update(section, data, options, call_id, user_name) \
if(fsa_cib_conn != NULL) { \
call_id = cib_internal_op( \
fsa_cib_conn, CIB_OP_MODIFY, NULL, section, data, \
NULL, options, user_name); \
\
} else { \
crm_err("No CIB connection available"); \
}
# define fsa_cib_anon_update(section, data, options) \
if(fsa_cib_conn != NULL) { \
fsa_cib_conn->cmds->modify( \
fsa_cib_conn, section, data, options); \
\
} else { \
crm_err("No CIB connection available"); \
}
extern gboolean fsa_has_quorum;
extern int last_peer_update;
extern int last_resource_update;
enum node_update_flags {
node_update_none = 0x0000,
node_update_quick = 0x0001,
node_update_cluster = 0x0010,
node_update_peer = 0x0020,
node_update_join = 0x0040,
node_update_expected = 0x0100,
node_update_all = node_update_cluster|node_update_peer|node_update_join|node_update_expected,
};
gboolean crm_timer_stop(fsa_timer_t * timer);
gboolean crm_timer_start(fsa_timer_t * timer);
gboolean crm_timer_popped(gpointer data);
gboolean is_timer_started(fsa_timer_t * timer);
int crmd_exit(int rc);
int crmd_fast_exit(int rc);
gboolean stop_subsystem(struct crm_subsystem_s *centry, gboolean force_quit);
gboolean start_subsystem(struct crm_subsystem_s *centry);
void fsa_dump_actions(long long action, const char *text);
void fsa_dump_inputs(int log_level, const char *text, long long input_register);
gboolean update_dc(xmlNode * msg);
void crm_update_peer_join(const char *source, crm_node_t * node, enum crm_join_phase phase);
xmlNode *create_node_state_update(crm_node_t *node, int flags,
xmlNode *parent, const char *source);
void populate_cib_nodes(enum node_update_flags flags, const char *source);
void crm_update_quorum(gboolean quorum, gboolean force_update);
void erase_status_tag(const char *uname, const char *tag, int options);
void init_transient_attrs(const char *uname, const char *start_state, int options);
void update_attrd(const char *host, const char *name, const char *value, const char *user_name, gboolean is_remote_node);
void update_attrd_remote_node_removed(const char *host, const char *user_name);
void update_attrd_clear_failures(const char *host, const char *rsc,
const char *op, const char *interval,
gboolean is_remote_node);
int crmd_join_phase_count(enum crm_join_phase phase);
void crmd_join_phase_log(int level);
const char *get_timer_desc(fsa_timer_t * timer);
gboolean too_many_st_failures(void);
void st_fail_count_reset(const char * target);
void crmd_peer_down(crm_node_t *peer, bool full);
/* Convenience macro for registering a CIB callback
* (assumes that data can be freed with free())
*/
# define fsa_register_cib_callback(id, flag, data, fn) do { \
CRM_ASSERT(fsa_cib_conn); \
fsa_cib_conn->cmds->register_callback_full( \
fsa_cib_conn, id, 10 * (1 + crm_active_peers()), \
flag, data, #fn, fn, free); \
} while(0)
# define start_transition(state) do { \
switch(state) { \
case S_TRANSITION_ENGINE: \
register_fsa_action(A_TE_CANCEL); \
break; \
case S_POLICY_ENGINE: \
case S_IDLE: \
register_fsa_input(C_FSA_INTERNAL, I_PE_CALC, NULL); \
break; \
default: \
crm_debug("NOT starting a new transition in state %s", \
fsa_state2string(fsa_state)); \
break; \
} \
} while(0)
#endif

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:16 PM (16 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002551
Default Alt Text
(21 KB)

Event Timeline