From 22f1d29b828f627b08e9d9a56cf5acba7ec26623 Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Mon, 16 Feb 2015 12:46:58 -0800 Subject: [PATCH] Re-introduce the ORTE notifier framework for logging errors that would otherwise result in abort for persistent systems. Thanks to L. Rajeshnarayanan of Intel for the contribution Subsequent commits will integrate this capability with the state and errmgr frameworks. --- orte/mca/notifier/Makefile.am | 39 +++ orte/mca/notifier/base/Makefile.am | 27 ++ orte/mca/notifier/base/base.h | 97 ++++++ orte/mca/notifier/base/notifier_base_fns.c | 143 ++++++++ orte/mca/notifier/base/notifier_base_frame.c | 254 ++++++++++++++ orte/mca/notifier/base/notifier_base_select.c | 196 +++++++++++ orte/mca/notifier/notifier.h | 144 ++++++++ orte/mca/notifier/smtp/.opal_ignore | 0 orte/mca/notifier/smtp/Makefile.am | 52 +++ orte/mca/notifier/smtp/configure.m4 | 39 +++ .../notifier/smtp/help-orcm-notifier-smtp.txt | 33 ++ orte/mca/notifier/smtp/notifier_smtp.h | 68 ++++ .../notifier/smtp/notifier_smtp_component.c | 198 +++++++++++ orte/mca/notifier/smtp/notifier_smtp_module.c | 328 ++++++++++++++++++ orte/mca/notifier/syslog/Makefile.am | 45 +++ orte/mca/notifier/syslog/notifier_syslog.h | 40 +++ .../syslog/notifier_syslog_component.c | 61 ++++ .../notifier/syslog/notifier_syslog_module.c | 88 +++++ 18 files changed, 1852 insertions(+) create mode 100644 orte/mca/notifier/Makefile.am create mode 100644 orte/mca/notifier/base/Makefile.am create mode 100644 orte/mca/notifier/base/base.h create mode 100644 orte/mca/notifier/base/notifier_base_fns.c create mode 100644 orte/mca/notifier/base/notifier_base_frame.c create mode 100644 orte/mca/notifier/base/notifier_base_select.c create mode 100644 orte/mca/notifier/notifier.h create mode 100644 orte/mca/notifier/smtp/.opal_ignore create mode 100644 orte/mca/notifier/smtp/Makefile.am create mode 100644 orte/mca/notifier/smtp/configure.m4 create mode 100644 orte/mca/notifier/smtp/help-orcm-notifier-smtp.txt create mode 100644 orte/mca/notifier/smtp/notifier_smtp.h create mode 100644 orte/mca/notifier/smtp/notifier_smtp_component.c create mode 100644 orte/mca/notifier/smtp/notifier_smtp_module.c create mode 100644 orte/mca/notifier/syslog/Makefile.am create mode 100644 orte/mca/notifier/syslog/notifier_syslog.h create mode 100644 orte/mca/notifier/syslog/notifier_syslog_component.c create mode 100644 orte/mca/notifier/syslog/notifier_syslog_module.c diff --git a/orte/mca/notifier/Makefile.am b/orte/mca/notifier/Makefile.am new file mode 100644 index 00000000000..303a6bfd91f --- /dev/null +++ b/orte/mca/notifier/Makefile.am @@ -0,0 +1,39 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2014 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# main library setup +noinst_LTLIBRARIES = libmca_notifier.la +libmca_notifier_la_SOURCES = + +# local files +headers = notifier.h + +libmca_notifier_la_SOURCES += $(headers) + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +ortedir = $(includedir)/openmpi/$(subdir) +nobase_orte_HEADERS = $(headers) +endif + +include base/Makefile.am + +distclean-local: + rm -f base/static-components.h diff --git a/orte/mca/notifier/base/Makefile.am b/orte/mca/notifier/base/Makefile.am new file mode 100644 index 00000000000..877953d0829 --- /dev/null +++ b/orte/mca/notifier/base/Makefile.am @@ -0,0 +1,27 @@ +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2014-2015 Intel, Inc. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers += \ + base/base.h + +libmca_notifier_la_SOURCES += \ + base/notifier_base_frame.c \ + base/notifier_base_select.c \ + base/notifier_base_fns.c diff --git a/orte/mca/notifier/base/base.h b/orte/mca/notifier/base/base.h new file mode 100644 index 00000000000..cbed897a35d --- /dev/null +++ b/orte/mca/notifier/base/base.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * + * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** @file: + */ + +#ifndef MCA_NOTIFIER_BASE_H +#define MCA_NOTIFIER_BASE_H + +/* + * includes + */ +#include "orte_config.h" + +#include "opal/class/opal_list.h" +#include "opal/mca/base/base.h" +#include "opal/mca/event/event.h" + +#include "orte/mca/notifier/notifier.h" + +BEGIN_C_DECLS + +/* + * MCA Framework + */ +ORTE_DECLSPEC extern mca_base_framework_t orte_notifier_base_framework; + +typedef struct { + opal_event_base_t *ev_base; + bool ev_base_active; + opal_pointer_array_t modules; + orte_notifier_severity_t severity_level; + char *default_actions; + char *emerg_actions; + char *alert_actions; + char *crit_actions; + char *warn_actions; + char *notice_actions; + char *info_actions; + char *debug_actions; + char *error_actions; +} orte_notifier_base_t; + +/* + * Type for holding selected module / component pairs + */ +typedef struct { + opal_list_item_t super; + /* Component */ + orte_notifier_base_component_t *component; + /* Module */ + orte_notifier_base_module_t *module; + /* Priority */ + int priority; +} orte_notifier_active_module_t; +OBJ_CLASS_DECLARATION(orte_notifier_active_module_t); + +typedef struct { + opal_object_t super; + opal_event_t ev; + char **modules; + orte_notifier_severity_t severity; + int errcode; + const char *msg; + va_list *ap; +} orte_notifier_request_t; +OBJ_CLASS_DECLARATION(orte_notifier_request_t); + +ORTE_DECLSPEC extern orte_notifier_base_t orte_notifier_base; +ORTE_DECLSPEC extern orte_notifier_severity_t orte_notifier_severity; +/* select a component */ +ORTE_DECLSPEC int orte_notifier_base_select(void); +/* log function */ +ORTE_DECLSPEC void orte_notifier_base_log(orte_notifier_severity_t severity, + int errcode, const char *msg, ...); +/* severity to string */ +ORTE_DECLSPEC const char* orte_notifier_base_sev2str(orte_notifier_severity_t severity); +END_C_DECLS +#endif diff --git a/orte/mca/notifier/base/notifier_base_fns.c b/orte/mca/notifier/base/notifier_base_fns.c new file mode 100644 index 00000000000..458b5192a2b --- /dev/null +++ b/orte/mca/notifier/base/notifier_base_fns.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#include "orte_config.h" + +#include "opal/mca/event/event.h" +#include "opal/runtime/opal_progress_threads.h" + +#include "orte/constants.h" +#include "orte/mca/ess/ess.h" +#include "orte/util/error_strings.h" +#include "orte/util/name_fns.h" +#include "orte/runtime/orte_globals.h" + +#include "orte/mca/notifier/base/base.h" + + +static void process_log(int fd, short args, void *cbdata) +{ + int i = 0, j = 0; + orte_notifier_active_module_t *i_module; + orte_notifier_request_t *req = (orte_notifier_request_t *)cbdata; + char **modules = req->modules; + + /* call the log function of all modules in priority order */ + for (i = 0; i < orte_notifier_base.modules.size; i++) { + if (NULL == (i_module = (orte_notifier_active_module_t*)opal_pointer_array_get_item (&orte_notifier_base.modules, i))) { + continue; + } + for (j = 0; NULL != modules[j]; j++) { + if (0 == strncasecmp(i_module->component->base_version.mca_component_name, modules[j], strlen(modules[j]))) { + if (NULL != i_module->module->log) { + i_module->module->log(req->severity, req->errcode, req->msg, req->ap); + va_end(*req->ap); + } + } + } + } +} + +void orte_notifier_base_log(orte_notifier_severity_t severity, + int errcode, const char *msg, ...) +{ + va_list ap; + char **modules; + orte_notifier_request_t *req; + + /* if no modules are active, then there is nothing to do */ + if (0 == orte_notifier_base.modules.size) { + return; + } + + /* check if the severity is >= severity level set for reporting */ + if (orte_notifier_base.severity_level < severity ) { + return; + } + + if (ORTE_NOTIFIER_EMERG == severity && + (NULL != orte_notifier_base.emerg_actions)) { + modules = opal_argv_split(orte_notifier_base.emerg_actions, ','); + } else if (ORTE_NOTIFIER_ALERT == severity && + (NULL != orte_notifier_base.alert_actions)) { + modules = opal_argv_split(orte_notifier_base.alert_actions, ','); + } else if (ORTE_NOTIFIER_CRIT == severity && + (NULL != orte_notifier_base.crit_actions)) { + modules = opal_argv_split(orte_notifier_base.crit_actions, ','); + } else if (ORTE_NOTIFIER_WARN == severity && + (NULL != orte_notifier_base.warn_actions)) { + modules = opal_argv_split(orte_notifier_base.warn_actions, ','); + } else if (ORTE_NOTIFIER_NOTICE == severity && + (NULL != orte_notifier_base.notice_actions)) { + modules = opal_argv_split(orte_notifier_base.notice_actions, ','); + } else if (ORTE_NOTIFIER_INFO == severity && + (NULL != orte_notifier_base.info_actions)) { + modules = opal_argv_split(orte_notifier_base.info_actions, ','); + } else if (ORTE_NOTIFIER_DEBUG == severity && + (NULL != orte_notifier_base.debug_actions)) { + modules = opal_argv_split(orte_notifier_base.debug_actions, ','); + } else if (ORTE_NOTIFIER_ERROR == severity && + (NULL != orte_notifier_base.error_actions)) { + modules = opal_argv_split(orte_notifier_base.error_actions, ','); + } else if (NULL != orte_notifier_base.default_actions) { + modules = opal_argv_split(orte_notifier_base.default_actions, ','); + } else { + /* no modules selected */ + return; + } + + /* set the event base and push this request into event base + */ + req = OBJ_NEW(orte_notifier_request_t); + + req->modules = modules; + req->severity = severity; + req->errcode = errcode; + req->msg = msg; + va_start(ap, msg); + req->ap = ≈ + + /* + * set the event and activate + */ + opal_event_set(orte_notifier_base.ev_base, &req->ev, -1, + OPAL_EV_WRITE, + process_log, req); + opal_event_set_priority(&req->ev, OPAL_EV_SYS_HI_PRI); + opal_event_active (&req->ev, OPAL_EV_WRITE, 1); +} + + +const char* orte_notifier_base_sev2str(orte_notifier_severity_t severity) +{ + switch (severity) { + case ORTE_NOTIFIER_EMERG: return "EMERG"; break; + case ORTE_NOTIFIER_ALERT: return "ALERT"; break; + case ORTE_NOTIFIER_CRIT: return "CRIT"; break; + case ORTE_NOTIFIER_ERROR: return "ERROR"; break; + case ORTE_NOTIFIER_WARN: return "WARN"; break; + case ORTE_NOTIFIER_NOTICE: return "NOTICE"; break; + case ORTE_NOTIFIER_INFO: return "INFO"; break; + case ORTE_NOTIFIER_DEBUG: return "DEBUG"; break; + default: return "UNKNOWN"; break; + } +} + diff --git a/orte/mca/notifier/base/notifier_base_frame.c b/orte/mca/notifier/base/notifier_base_frame.c new file mode 100644 index 00000000000..4fc952d7400 --- /dev/null +++ b/orte/mca/notifier/base/notifier_base_frame.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#include "orte_config.h" +#include "orte/constants.h" + +#ifdef HAVE_STRING_H +#include +#endif + +#include "opal/mca/mca.h" +#include "opal/util/argv.h" +#include "opal/util/fd.h" +#include "opal/util/output.h" +#include "opal/mca/base/base.h" +#include "opal/class/opal_pointer_array.h" +#include "opal/runtime/opal_progress_threads.h" +#include "orte/mca/notifier/base/base.h" + +/* default module to use for logging*/ +#define ORTE_NOTIFIER_DEFAULT_MODULE "syslog" + +/* + * The following file was created by configure. It contains extern + * statements and the definition of an array of pointers to each + * component's public mca_base_component_t struct. + */ + +#include "orte/mca/notifier/base/static-components.h" + +/* + * Global variables + */ +opal_list_t orte_notifier_base_components_available; + +orte_notifier_base_API_module_t orte_notifier = { + orte_notifier_base_log +}; + +orte_notifier_base_t orte_notifier_base; + +static char *notifier_severity = NULL; + +/** + * Function for selecting a set of components from all those that are + * available. + * + * Examples: + * 1) + * -mca notifier syslog,smtp + * --> syslog and smtp are selected for the loging + */ +static int orte_notifier_base_register(mca_base_register_flag_t flags) +{ + /* let the user define a base level of severity to report */ + (void) mca_base_var_register("orte", "notifier", "base", "severity_level", + "Report all events at or above this severity [default: error]", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + ¬ifier_severity); + if (NULL == notifier_severity) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_ERROR; + } else if (0 == strncasecmp(notifier_severity, "emerg", strlen("emerg"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_EMERG; + } else if (0 == strncasecmp(notifier_severity, "alert", strlen("alert"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_ALERT; + } else if (0 == strncasecmp(notifier_severity, "crit", strlen("crit"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_CRIT; + } else if (0 == strncasecmp(notifier_severity, "warn", strlen("warn"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_WARN; + } else if (0 == strncasecmp(notifier_severity, "notice", strlen("notice"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_NOTICE; + } else if (0 == strncasecmp(notifier_severity, "info", strlen("info"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_INFO; + } else if (0 == strncasecmp(notifier_severity, "debug", strlen("debug"))) { + orte_notifier_base.severity_level = ORTE_NOTIFIER_DEBUG; + } else { + orte_notifier_base.severity_level = ORTE_NOTIFIER_ERROR; + } + + /* let the user define a base default actions */ + orte_notifier_base.default_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "default_actions", + "Report all events to the default actions:NONE,syslog,smtp", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.default_actions); + + if (NULL == orte_notifier_base.default_actions) { + orte_notifier_base.default_actions = strdup(ORTE_NOTIFIER_DEFAULT_MODULE); + } + /* let the user define a action for emergency events */ + orte_notifier_base.emerg_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "emerg_event_actions", + "Report emergency events to the specified actions: example 'smtp'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.emerg_actions); + + /* let the user define a action for alert events */ + orte_notifier_base.alert_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "alert_event_actions", + "Report alert events to the specified actions: example 'smtp'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.alert_actions); + + /* let the user define a action for critical events */ + orte_notifier_base.crit_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "crit_event_actions", + "Report critical events to the specified actions: example 'syslog'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.crit_actions); + + /* let the user define a action for warning events */ + orte_notifier_base.warn_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "warn_event_actions", + "Report warning events to the specified actions: example 'syslog'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.warn_actions); + + /* let the user define a action for notice events */ + orte_notifier_base.notice_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "notice_event_actions", + "Report notice events to the specified actions: example 'syslog'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.notice_actions); + + /* let the user define a action for info events */ + orte_notifier_base.info_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "info_event_actions", + "Report info events to the specified actions: example 'syslog'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.info_actions); + + /* let the user define a action for debug events */ + orte_notifier_base.debug_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "debug_event_actions", + "Report debug events to the specified actions: example 'syslog'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.debug_actions); + + /* let the user define a action for error events */ + orte_notifier_base.error_actions = NULL; + (void) mca_base_var_register("orte", "notifier", "base", "error_event_actions", + "Report error events to the specified actions: example 'syslog'", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &orte_notifier_base.error_actions); + + return ORTE_SUCCESS; +} + +static int orte_notifier_base_close(void) +{ + orte_notifier_active_module_t *i_module; + int i; + + for (i = 0; i < orte_notifier_base.modules.size; i++) { + if (NULL == (i_module = (orte_notifier_active_module_t*) + opal_pointer_array_get_item(&orte_notifier_base.modules, + i))) { + continue; + } + if (NULL != i_module->module->finalize) { + i_module->module->finalize(); + } + } + OBJ_DESTRUCT(&orte_notifier_base.modules); + + if (orte_notifier_base.ev_base_active) { + orte_notifier_base.ev_base_active = false; + opal_stop_progress_thread("notifier", true); + } + + /* close all remaining available components */ + return mca_base_framework_components_close(&orte_notifier_base_framework, NULL); +} + +/** + * Function for finding and opening either all MCA components, or the one + * that was specifically requested via a MCA parameter. + */ +static int orte_notifier_base_open(mca_base_open_flag_t flags) +{ + /* construct the array of modules */ + OBJ_CONSTRUCT(&orte_notifier_base.modules, opal_pointer_array_t); + opal_pointer_array_init (&orte_notifier_base.modules, 3, INT_MAX, 1); + + /* create our own event base */ + orte_notifier_base.ev_base_active = true; + if (NULL == (orte_notifier_base.ev_base = + opal_start_progress_thread("notifier", true))) { + orte_notifier_base.ev_base_active = false; + return ORTE_ERROR; + } + + /* Open up all available components */ + return mca_base_framework_components_open(&orte_notifier_base_framework, + flags); +} + +MCA_BASE_FRAMEWORK_DECLARE(orte, notifier, "ORTE Notifier Framework", + orte_notifier_base_register, + orte_notifier_base_open, orte_notifier_base_close, + mca_notifier_base_static_components, 0); + + +static void cons (orte_notifier_active_module_t *t) +{ +} +OBJ_CLASS_INSTANCE (orte_notifier_active_module_t, + opal_object_t, + cons, NULL); + +static void req_cons (orte_notifier_request_t *t) +{ +} +OBJ_CLASS_INSTANCE (orte_notifier_request_t, + opal_object_t, + req_cons, NULL); diff --git a/orte/mca/notifier/base/notifier_base_select.c b/orte/mca/notifier/base/notifier_base_select.c new file mode 100644 index 00000000000..31bab1ac13d --- /dev/null +++ b/orte/mca/notifier/base/notifier_base_select.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014-2015 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#include "orte_config.h" + +#ifdef HAVE_STRING_H +#include +#endif + +#include "opal/mca/mca.h" +#include "opal/mca/base/base.h" +#include "opal/util/argv.h" +#include "opal/util/output.h" +#include "opal/class/opal_pointer_array.h" + +#include "orte/mca/notifier/base/base.h" + +/* Global variables */ +/* + * orte_notifier_base_selected is set to true if at least 1 module has + * been selected for the notifier log API interface. + */ +static bool orte_notifier_base_selected = false; + +/** + * Function for weeding out notifier components that don't want to run. + * + * Call the init function on all available compoenent to find out if + * they want to run. Select all components that don't fail. Failing + * Components will be closed and unloaded. The selected modules will + * be returned to the called in a opal_list_t. + */ + +int orte_notifier_base_select(void) +{ + mca_base_component_list_item_t *cli = NULL; + orte_notifier_base_component_t *component = NULL; + mca_base_module_t *module = NULL; + orte_notifier_active_module_t *i_module; + int priority = 0, i, j, low_i; + opal_pointer_array_t tmp_array; + bool none_found; + orte_notifier_active_module_t *tmp_module = NULL, *tmp_module_sw = NULL; + + + if (orte_notifier_base_selected) { + return ORTE_SUCCESS; + } + orte_notifier_base_selected = true; + + OBJ_CONSTRUCT(&tmp_array, opal_pointer_array_t); + + opal_output_verbose(10, orte_notifier_base_framework.framework_output, + "notifier:base:select: Auto-selecting components"); + + /* + * Traverse the list of available components. + * For each call their 'query' functions to determine relative priority. + */ + none_found = true; + OPAL_LIST_FOREACH(cli, &orte_notifier_base_framework.framework_components, mca_base_component_list_item_t) { + component = (orte_notifier_base_component_t *) cli->cli_component; + + /* + * If there is a query function then use it. + */ + if (NULL == component->base_version.mca_query_component) { + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:base:select Skipping component [%s]. It does not implement a query function", + component->base_version.mca_component_name ); + continue; + } + + /* + * Query this component for the module and priority + */ + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:base:select Querying component [%s]", + component->base_version.mca_component_name); + + component->base_version.mca_query_component(&module, &priority); + + /* + * If no module was returned or negative priority, then skip component + */ + if (NULL == module || priority < 0) { + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:base:select Skipping component [%s]. Query failed to return a module", + component->base_version.mca_component_name ); + continue; + } + + /* + * Append them to the temporary list, we will sort later + */ + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:base:select Query of component [%s] set priority to %d", + component->base_version.mca_component_name, priority); + tmp_module = OBJ_NEW(orte_notifier_active_module_t); + tmp_module->component = component; + tmp_module->module = (orte_notifier_base_module_t*)module; + tmp_module->priority = priority; + + opal_pointer_array_add(&tmp_array, (void*)tmp_module); + none_found = false; + } + + if (none_found) { + /* okay for no modules to be found */ + return ORTE_SUCCESS; + } + + /* + * Sort the list by decending priority + */ + priority = 0; + for(j = 0; j < tmp_array.size; ++j) { + tmp_module_sw = (orte_notifier_active_module_t*)opal_pointer_array_get_item(&tmp_array, j); + if( NULL == tmp_module_sw ) { + continue; + } + + low_i = -1; + priority = tmp_module_sw->priority; + + for(i = 0; i < tmp_array.size; ++i) { + tmp_module = (orte_notifier_active_module_t*)opal_pointer_array_get_item(&tmp_array, i); + if( NULL == tmp_module ) { + continue; + } + if( tmp_module->priority > priority ) { + low_i = i; + priority = tmp_module->priority; + } + } + + if( low_i >= 0 ) { + tmp_module = (orte_notifier_active_module_t*)opal_pointer_array_get_item(&tmp_array, low_i); + if ( NULL == tmp_module ) { + continue; + } + opal_pointer_array_set_item(&tmp_array, low_i, NULL); + j--; /* Try this entry again, if it is not the lowest */ + } else { + tmp_module = tmp_module_sw; + opal_pointer_array_set_item(&tmp_array, j, NULL); + } + if ( tmp_module ) { + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:base:select Add module with priority [%s] %d", + tmp_module->component->base_version.mca_component_name, tmp_module->priority); + opal_pointer_array_add(&orte_notifier_base.modules, tmp_module); + } + } + OBJ_DESTRUCT(&tmp_array); + + /* + * Initialize each of the modules in priority order from + * highest to lowest + */ + for(i = 0; i < orte_notifier_base.modules.size; ++i) { + i_module = (orte_notifier_active_module_t*)opal_pointer_array_get_item(&orte_notifier_base.modules, i); + if( NULL == i_module ) { + continue; + } + if( NULL != i_module->module->init ) { + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:base:init module called with priority [%s] %d", + i_module->component->base_version.mca_component_name, i_module->priority); + if (ORTE_SUCCESS != i_module->module->init()) { + opal_pointer_array_set_item(&orte_notifier_base.modules, i, NULL); + OBJ_RELEASE(i_module); + } + } + } + + return ORTE_SUCCESS; +} diff --git a/orte/mca/notifier/notifier.h b/orte/mca/notifier/notifier.h new file mode 100644 index 00000000000..7c2cd3dd594 --- /dev/null +++ b/orte/mca/notifier/notifier.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All Rights Reserved. + * Copyright (c) 2012 Los Alamos National Security, LLC. + * All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +/** @file: + * + * The OpenRTE Notifier Framework + * + * The OpenRTE Notifier framework provides a mechanism for notifying + * system administrators or other fault monitoring systems that a + * problem with the underlying cluster has been detected - e.g., a + * failed connection in a network fabric + */ + +#ifndef MCA_NOTIFIER_H +#define MCA_NOTIFIER_H + +/* + * includes + */ + +#include "orte_config.h" + +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_LIMITS_H +#include +#endif +#ifdef HAVE_SYSLOG_H +#include +#endif + +#include "opal/mca/mca.h" + +#include "orte/constants.h" +#include "orte/types.h" + + +BEGIN_C_DECLS + +/* The maximum size of any on-stack buffers used in the notifier + * so we can try to avoid calling malloc in OUT_OF_RESOURCES conditions. + * The code has NOT been auditied for use of malloc, so this still + * may fail to get the "OUT_OF_RESOURCE" message out. Oh Well. + */ +#define ORTE_NOTIFIER_MAX_BUF 512 + +/* Severities */ +typedef enum { + ORTE_NOTIFIER_EMERG = LOG_EMERG, + ORTE_NOTIFIER_ALERT = LOG_ALERT, + ORTE_NOTIFIER_CRIT = LOG_CRIT, + ORTE_NOTIFIER_ERROR = LOG_ERR, + ORTE_NOTIFIER_WARN = LOG_WARNING, + ORTE_NOTIFIER_NOTICE = LOG_NOTICE, + ORTE_NOTIFIER_INFO = LOG_INFO, + ORTE_NOTIFIER_DEBUG = LOG_DEBUG +} orte_notifier_severity_t; + +/* + * Component functions - all MUST be provided! + */ + +/* initialize the selected module */ +typedef int (*orte_notifier_base_module_init_fn_t)(void); + +/* finalize the selected module */ +typedef void (*orte_notifier_base_module_finalize_fn_t)(void); + +/* Log a failure message */ +typedef void (*orte_notifier_base_module_log_fn_t)(orte_notifier_severity_t severity, int errcode, const char *msg, va_list *ap) + __opal_attribute_format_funcptr__(__printf__, 3, 0); + + +/* + * Ver 1.0 + */ +struct orte_notifier_base_module_1_0_0_t { + orte_notifier_base_module_init_fn_t init; + orte_notifier_base_module_finalize_fn_t finalize; + orte_notifier_base_module_log_fn_t log; +}; + +typedef struct orte_notifier_base_module_1_0_0_t orte_notifier_base_module_1_0_0_t; +typedef orte_notifier_base_module_1_0_0_t orte_notifier_base_module_t; + +/* + * API functions + */ +/* Log a failure message */ +typedef void (*orte_notifier_base_API_log_fn_t)(orte_notifier_severity_t severity, int errcode, const char *msg, ...); + +/* + * Define a struct to hold the API functions that users will call + */ +struct orte_notifier_base_API_module_1_0_0_t { + orte_notifier_base_API_log_fn_t log; +}; +typedef struct orte_notifier_base_API_module_1_0_0_t orte_notifier_base_API_module_1_0_0_t; +typedef orte_notifier_base_API_module_1_0_0_t orte_notifier_base_API_module_t; + +ORTE_DECLSPEC extern orte_notifier_base_API_module_t orte_notifier; + +/* + * the standard component data structure + */ +struct orte_notifier_base_component_1_0_0_t { + mca_base_component_t base_version; + mca_base_component_data_t base_data; +}; +typedef struct orte_notifier_base_component_1_0_0_t orte_notifier_base_component_1_0_0_t; +typedef orte_notifier_base_component_1_0_0_t orte_notifier_base_component_t; + + +/* + * Macro for use in components that are of type notifier v1.0.0 + */ +#define ORTE_NOTIFIER_BASE_VERSION_1_0_0 \ + /* notifier v1.0 is chained to MCA v2.0 */ \ + MCA_BASE_VERSION_2_0_0, \ + /* notifier v1.0 */ \ + "notifier", 1, 0, 0 + +END_C_DECLS + +#endif /* MCA_NOTIFIER_H */ diff --git a/orte/mca/notifier/smtp/.opal_ignore b/orte/mca/notifier/smtp/.opal_ignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/orte/mca/notifier/smtp/Makefile.am b/orte/mca/notifier/smtp/Makefile.am new file mode 100644 index 00000000000..336fd4603cc --- /dev/null +++ b/orte/mca/notifier/smtp/Makefile.am @@ -0,0 +1,52 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2014 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AM_CPPFLAGS = $(notifier_smtp_CPPFLAGS) + +dist_ortedata_DATA = \ + help-orte-notifier-smtp.txt + +sources = \ + notifier_smtp.h \ + notifier_smtp_module.c \ + notifier_smtp_component.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_orte_notifier_smtp_DSO +component_noinst = +component_install = mca_notifier_smtp.la +else +component_noinst = libmca_notifier_smtp.la +component_install = +endif + +mcacomponentdir = $(ortelibdir) +mcacomponent_LTLIBRARIES = $(component_install) +mca_notifier_smtp_la_SOURCES = $(sources) +mca_notifier_smtp_la_LDFLAGS = -module -avoid-version $(notifier_smtp_LDFLAGS) +mca_notifier_smtp_la_LIBADD = $(notifier_smtp_LIBS) + +noinst_LTLIBRARIES = $(component_noinst) +libmca_notifier_smtp_la_SOURCES =$(sources) +libmca_notifier_smtp_la_LDFLAGS = -module -avoid-version $(notifier_smtp_LDFLAGS) +libmca_notifier_smtp_la_LIBADD = $(notifier_smtp_LIBS) diff --git a/orte/mca/notifier/smtp/configure.m4 b/orte/mca/notifier/smtp/configure.m4 new file mode 100644 index 00000000000..0ee0f956fb3 --- /dev/null +++ b/orte/mca/notifier/smtp/configure.m4 @@ -0,0 +1,39 @@ +# -*- shell-script -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2014 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# MCA_notifier_smtp_CONFIG([action-if-found], [action-if-not-found]) +# ----------------------------------------------------------- +AC_DEFUN([MCA_orte_notifier_smtp_CONFIG], [ + AC_CONFIG_FILES([orte/mca/notifier/smtp/Makefile]) + + AC_CHECK_TYPES( [include/libesmtp.h], + [libesmtp*], + [libesmtp.h], + [esmtp], + [smtp_create_session], + [], + [orte_notifier_want_smtp=1], + [orte_notifier_want_smtp=0]) + + AS_IF([test "$orte_notifier_want_smtp" = 1], + [$1], + [$2]) +])dnl diff --git a/orte/mca/notifier/smtp/help-orcm-notifier-smtp.txt b/orte/mca/notifier/smtp/help-orcm-notifier-smtp.txt new file mode 100644 index 00000000000..b03438387cc --- /dev/null +++ b/orte/mca/notifier/smtp/help-orcm-notifier-smtp.txt @@ -0,0 +1,33 @@ +# -*- text -*- +# +# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# +# This is the US/English help file for Open MPI's SMTP notifier support +# +[to/from not specified] +Error: the Open MPI SMTP notifier component had no "to" and/or "from" +email addresses specified. +# +[server not specified] +Error: the Open MPI SMTP notifier component had no SMTP server name or +IP address specified. +# +[unable to resolve server] +Sorry, Open MPI's SMTP notifier component was unable to resolve the IP +address of the server provided. + + Server: %s +# +[send_email failed] +Oops! Open MPI's SMTP notifier failed to send an email. + + Reason: %s + libESMTP function: %s + libESMTP message: %s + Message: %s +# diff --git a/orte/mca/notifier/smtp/notifier_smtp.h b/orte/mca/notifier/smtp/notifier_smtp.h new file mode 100644 index 00000000000..0d381450dc8 --- /dev/null +++ b/orte/mca/notifier/smtp/notifier_smtp.h @@ -0,0 +1,68 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef NOTIFIER_SMTP_H +#define NOTIFIER_SMTP_H + +#include "orte_config.h" + +#include + +#include "libesmtp.h" + +#include "orte/mca/notifier/notifier.h" + +BEGIN_C_DECLS + +typedef struct { + orte_notifier_base_component_t super; + + /* libesmtp version */ + char *version; + + /* SMTP server name and port */ + char *server; + int port; + + /* To, From, Subject */ + char *to, **to_argv, *from_name, *from_addr, *subject; + + /* Mail body prefix and suffix */ + char *body_prefix, *body_suffix; + + /* struct hostent from resolved SMTP server name */ + struct hostent *server_hostent; + + /* Priority of this component */ + int priority; +} orte_notifier_smtp_component_t; + + +/* + * Notifier interfaces + */ +ORTE_MODULE_DECLSPEC extern orte_notifier_smtp_component_t + mca_notifier_smtp_component; +extern orte_notifier_base_module_t orte_notifier_smtp_module; + +END_C_DECLS + +#endif diff --git a/orte/mca/notifier/smtp/notifier_smtp_component.c b/orte/mca/notifier/smtp/notifier_smtp_component.c new file mode 100644 index 00000000000..e016b2d9a01 --- /dev/null +++ b/orte/mca/notifier/smtp/notifier_smtp_component.c @@ -0,0 +1,198 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ +*/ + +/* + * Simple smtp notifier (using libesmtp) + */ + +#include "orte_config.h" + +#include "opal/mca/base/mca_base_var.h" + +#include "orte/constants.h" +#include "orte/util/show_help.h" + +#include "notifier_smtp.h" + +static int smtp_component_query(mca_base_module_t **module, int *priority); +static int smtp_close(void); +static int smtp_register(void); + +/* + * Struct of function pointers that need to be initialized + */ +orte_notifier_smtp_component_t mca_notifier_smtp_component = { + { + { + ORTE_NOTIFIER_BASE_VERSION_1_0_0, + + "smtp", + + ORTE_MAJOR_VERSION, + ORTE_MINOR_VERSION, + ORTE_RELEASE_VERSION, + + NULL, + smtp_close, + smtp_component_query, + smtp_register, + }, + { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + } + }, +}; + +static int smtp_register(void) +{ + char version[256]; + + /* Server stuff */ + mca_notifier_smtp_component.server = strdup("localhost"); + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "server", + "SMTP server name or IP address", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.server); + + mca_notifier_smtp_component.port = 25; + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "port", + "SMTP server port", + MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.port); + + /* Email stuff */ + mca_notifier_smtp_component.to = NULL; + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "to", + "Comma-delimited list of email addresses to send to", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.to); + mca_notifier_smtp_component.from_addr = NULL; + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "from_addr", + "Email address that messages will be from", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.from_addr); + mca_notifier_smtp_component.from_name = strdup("ORTE Notifier"); + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "from_name", + "Email name that messages will be from", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.from_name); + mca_notifier_smtp_component.subject = strdup("ORTE Notifier"); + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "subject", + "Email subject", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.subject); + + /* Mail body prefix and suffix */ + mca_notifier_smtp_component.body_prefix = strdup("The ORTE SMTP notifier wishes to inform you of the following message:\n\n"); + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "body_prefix", + "Text to put at the beginning of the mail message", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.body_prefix); + mca_notifier_smtp_component.body_suffix = strdup("\n\nSincerely,\nOscar the ORTE Owl"); + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "body_prefix", + "Text to put at the end of the mail message", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.body_suffix); + + /* Priority */ + mca_notifier_smtp_component.priority = 10; + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "priority", + "Priority of this component", + MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.priority); + /* Libesmtp version */ + smtp_version(version, sizeof(version), 0); + version[sizeof(version) - 1] = '\0'; + mca_notifier_smtp_component.version = strdup(version); + (void) mca_base_component_var_register(&mca_notifier_smtp_component.super.base_version, "libesmtp_version", + "Version of libesmtp that this component is linked against", + MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, + OPAL_INFO_LVL_9, + MCA_BASE_VAR_SCOPE_READONLY, + &mca_notifier_smtp_component.version); + + return ORTE_SUCCESS; +} + +static int smtp_close(void) +{ + return ORTE_SUCCESS; +} + +static int smtp_component_query(mca_base_module_t **module, + int *priority) +{ + *priority = 0; + *module = NULL; + + /* If there's no to or from, there's no love */ + if (NULL == mca_notifier_smtp_component.to || + '\0' == mca_notifier_smtp_component.to[0] || + NULL == mca_notifier_smtp_component.from_addr || + '\0' == mca_notifier_smtp_component.from_addr[0]) { + orte_show_help("help-orte-notifier-smtp.txt", + "to/from not specified", true); + return ORTE_ERR_NOT_FOUND; + } + + /* Sanity checks */ + if (NULL == mca_notifier_smtp_component.server || + '\0' == mca_notifier_smtp_component.server[0]) { + orte_show_help("help-orte-notifier-smtp.txt", + "server not specified", true); + return ORTE_ERR_NOT_FOUND; + } + + /* Since we have to open a socket later, try to resolve the IP + address of the server now. Save the result, or abort if we + can't resolve it. */ + mca_notifier_smtp_component.server_hostent = + gethostbyname(mca_notifier_smtp_component.server); + if (NULL == mca_notifier_smtp_component.server_hostent) { + orte_show_help("help-orte-notifier-smtp.txt", + "unable to resolve server", + true, mca_notifier_smtp_component.server); + return ORTE_ERR_NOT_FOUND; + } + + *priority = 10; + *module = (mca_base_module_t *)&orte_notifier_smtp_module; + return ORTE_SUCCESS; +} diff --git a/orte/mca/notifier/smtp/notifier_smtp_module.c b/orte/mca/notifier/smtp/notifier_smtp_module.c new file mode 100644 index 00000000000..1e1a821b18f --- /dev/null +++ b/orte/mca/notifier/smtp/notifier_smtp_module.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* + * Send an email upon notifier events. + */ + +#include "orte_config.h" + +#include +#include +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif + +#include "opal/util/show_help.h" +#include "opal/util/argv.h" + +#include "orte/constants.h" +#include "orte/mca/ess/ess.h" +#include "orte/util/error_strings.h" +#include "orte/util/name_fns.h" +#include "orte/util/show_help.h" +#include "orte/runtime/orte_globals.h" +#include "orte/mca/notifier/base/base.h" + +#include "notifier_smtp.h" + + +/* Static API's */ +static void mylog(orte_notifier_base_severity_t severity, int errcode, + const char *msg, va_list ap); +static void myhelplog(orte_notifier_base_severity_t severity, int errcode, + const char *filename, + const char *topic, va_list ap); +static void mypeerlog(orte_notifier_base_severity_t severity, int errcode, + orte_process_name_t *peer_proc, + const char *msg, va_list ap); + +/* Module */ +orte_notifier_base_module_t orte_notifier_smtp_module = { + NULL, + NULL, + mylog, +}; + +typedef enum { + SENT_NONE, + SENT_HEADER, + SENT_BODY_PREFIX, + SENT_BODY, + SENT_BODY_SUFFIX, + SENT_ALL +} sent_flag_t; + +typedef struct { + sent_flag_t sent_flag; + char *msg; + char *prev_string; +} message_status_t; + +/* + * Convert lone \n's to \r\n + */ +static char *crnl(char *orig) +{ + int i, j, max, count; + char *str; + return strdup(orig); + + /* Count how much space we need */ + count = max = strlen(orig); + for (i = 0; i < max; ++i) { + if (orig[i] == '\n' && i > 0 && orig[i - 1] != '\r') { + ++count; + } + } + + /* Copy, changing \n to \r\n */ + str = malloc(count + 1); + for (j = i = 0; i < max; ++i) { + if (orig[i] == '\n' && i > 0 && orig[i - 1] != '\r') { + str[j++] = '\n'; + } + str[j++] = orig[i]; + } + str[j] = '\0'; + return str; +} + +/* + * Callback function invoked via smtp_start_session() + */ +static const char *message_cb(void **buf, int *len, void *arg) +{ + message_status_t *ms = (message_status_t*) arg; + + if (NULL == *buf) { + *buf = malloc(8192); + } + if (NULL == len) { + ms->sent_flag = SENT_NONE; + return NULL; + } + + /* Free the previous string */ + if (NULL != ms->prev_string) { + free(ms->prev_string); + ms->prev_string = NULL; + } + + switch (ms->sent_flag) { + case SENT_NONE: + /* Send a blank line to signify the end of the header */ + ms->sent_flag = SENT_HEADER; + ms->prev_string = NULL; + *len = 2; + return "\r\n"; + + case SENT_HEADER: + if (NULL != mca_notifier_smtp_component.body_prefix) { + ms->sent_flag = SENT_BODY_PREFIX; + ms->prev_string = crnl(mca_notifier_smtp_component.body_prefix); + *len = strlen(ms->prev_string); + return ms->prev_string; + } + + case SENT_BODY_PREFIX: + ms->sent_flag = SENT_BODY; + ms->prev_string = crnl(ms->msg); + *len = strlen(ms->prev_string); + return ms->prev_string; + + case SENT_BODY: + if (NULL != mca_notifier_smtp_component.body_suffix) { + ms->sent_flag = SENT_BODY_SUFFIX; + ms->prev_string = crnl(mca_notifier_smtp_component.body_suffix); + *len = strlen(ms->prev_string); + return ms->prev_string; + } + + case SENT_BODY_SUFFIX: + case SENT_ALL: + default: + ms->sent_flag = SENT_ALL; + *len = 0; + return NULL; + } +} + +/* + * Back-end function to actually send the email + */ +static int send_email(char *msg) +{ + int i, err = ORTE_SUCCESS; + char *str = NULL; + char *errmsg = NULL; + struct sigaction sig, oldsig; + bool set_oldsig = false; + smtp_session_t session = NULL; + smtp_message_t message = NULL; + message_status_t ms; + orte_notifier_smtp_component_t *c = &mca_notifier_smtp_component; + + if (NULL == c->to_argv) { + c->to_argv = opal_argv_split(c->to, ','); + if (NULL == c->to_argv || + NULL == c->to_argv[0]) { + return ORTE_ERR_OUT_OF_RESOURCE; + } + } + + ms.sent_flag = SENT_NONE; + ms.prev_string = NULL; + ms.msg = msg; + + /* Temporarily disable SIGPIPE so that if remote servers timeout + or hang up on us, it doesn't kill this application. We'll + restore the original SIGPIPE handler when we're done. */ + sig.sa_handler = SIG_IGN; + sigemptyset(&sig.sa_mask); + sig.sa_flags = 0; + sigaction(SIGPIPE, &sig, &oldsig); + set_oldsig = true; + + /* Try to get a libesmtp session. If so, assume that libesmtp is + happy and proceeed */ + session = smtp_create_session(); + if (NULL == session) { + err = ORTE_ERR_NOT_SUPPORTED; + errmsg = "stmp_create_session"; + goto error; + } + + /* Create the message */ + message = smtp_add_message(session); + if (NULL == message) { + err = ORTE_ERROR; + errmsg = "stmp_add_message"; + goto error; + } + + /* Set the SMTP server (yes, it's a weird return status!) */ + asprintf(&str, "%s:%d", c->server, c->port); + if (0 == smtp_set_server(session, str)) { + err = ORTE_ERROR; + errmsg = "stmp_set_server"; + goto error; + } + free(str); + str = NULL; + + /* Add the sender */ + if (0 == smtp_set_reverse_path(message, c->from_addr)) { + err = ORTE_ERROR; + errmsg = "stmp_set_reverse_path"; + goto error; + } + + /* Set the subject and some headers */ + asprintf(&str, "Open MPI SMTP Notifier v%d.%d.%d", + c->super.base_version.mca_component_major_version, + c->super.base_version.mca_component_minor_version, + c->super.base_version.mca_component_release_version); + if (0 == smtp_set_header(message, "Subject", c->subject) || + 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1) || + 0 == smtp_set_header(message, "To", NULL, NULL) || + 0 == smtp_set_header(message, "From", + (NULL != c->from_name ? + c->from_name : c->from_addr), + c->from_addr) || + 0 == smtp_set_header(message, "X-Mailer", str) || + 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1)) { + err = ORTE_ERROR; + errmsg = "smtp_set_header"; + goto error; + } + free(str); + str = NULL; + + /* Add the recipients */ + for (i = 0; NULL != c->to_argv[i]; ++i) { + if (NULL == smtp_add_recipient(message, c->to_argv[i])) { + err = ORTE_ERR_OUT_OF_RESOURCE; + errmsg = "stmp_add_recipient"; + goto error; + } + } + + /* Set the callback to get the message */ + if (0 == smtp_set_messagecb(message, message_cb, &ms)) { + err = ORTE_ERROR; + errmsg = "smtp_set_messagecb"; + goto error; + } + + /* Send it! */ + if (0 == smtp_start_session(session)) { + err = ORTE_ERROR; + errmsg = "smtp_start_session"; + goto error; + } + + /* Fall through */ + + error: + if (NULL != str) { + free(str); + } + if (NULL != session) { + smtp_destroy_session(session); + } + /* Restore the SIGPIPE handler */ + if (set_oldsig) { + sigaction(SIGPIPE, &oldsig, NULL); + } + if (ORTE_SUCCESS != err) { + int e; + char em[256]; + + e = smtp_errno(); + smtp_strerror(e, em, sizeof(em)); + orte_show_help("help-orte-notifier-smtp.txt", + "send_email failed", + true, "libesmtp library call failed", + errmsg, em, e, msg); + } + return err; +} + +static void mylog(orte_notifier_base_severity_t severity, int errcode, + const char *msg, va_list ap) +{ + char *output; + + /* If there was a message, output it */ + vasprintf(&output, msg, ap); + + if (NULL != output) { + send_email(output); + free(output); + } +} diff --git a/orte/mca/notifier/syslog/Makefile.am b/orte/mca/notifier/syslog/Makefile.am new file mode 100644 index 00000000000..f495ed5fc92 --- /dev/null +++ b/orte/mca/notifier/syslog/Makefile.am @@ -0,0 +1,45 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2014 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +sources = \ + notifier_syslog.h \ + notifier_syslog_module.c \ + notifier_syslog_component.c + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_orte_notifier_syslog_DSO +component_noinst = +component_install = mca_notifier_syslog.la +else +component_noinst = libmca_notifier_syslog.la +component_install = +endif + +mcacomponentdir = $(ortelibdir) +mcacomponent_LTLIBRARIES = $(component_install) +mca_notifier_syslog_la_SOURCES = $(sources) +mca_notifier_syslog_la_LDFLAGS = -module -avoid-version + +noinst_LTLIBRARIES = $(component_noinst) +libmca_notifier_syslog_la_SOURCES =$(sources) +libmca_notifier_syslog_la_LDFLAGS = -module -avoid-version diff --git a/orte/mca/notifier/syslog/notifier_syslog.h b/orte/mca/notifier/syslog/notifier_syslog.h new file mode 100644 index 00000000000..a83da1d0354 --- /dev/null +++ b/orte/mca/notifier/syslog/notifier_syslog.h @@ -0,0 +1,40 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ +#ifndef NOTIFIER_SYSLOG_H +#define NOTIFIER_SYSLOG_H + +#include "orte_config.h" + +#include "orte/mca/notifier/notifier.h" + +BEGIN_C_DECLS + +/* + * Notifier interfaces + */ + +ORTE_MODULE_DECLSPEC extern orte_notifier_base_component_t mca_notifier_syslog_component; +extern orte_notifier_base_module_t orte_notifier_syslog_module; + +END_C_DECLS + +#endif diff --git a/orte/mca/notifier/syslog/notifier_syslog_component.c b/orte/mca/notifier/syslog/notifier_syslog_component.c new file mode 100644 index 00000000000..93aca082021 --- /dev/null +++ b/orte/mca/notifier/syslog/notifier_syslog_component.c @@ -0,0 +1,61 @@ +/* -*- C -*- + * + * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ +*/ + +/* + * includes + */ +#include "orte_config.h" +#include "orte/constants.h" + +#include "notifier_syslog.h" + + +static int orte_notifier_syslog_component_query(mca_base_module_t **module, + int *priority); + +/* + * Struct of function pointers that need to be initialized + */ +orte_notifier_base_component_t mca_notifier_syslog_component = { + { + ORTE_NOTIFIER_BASE_VERSION_1_0_0, + + "syslog", /* MCA module name */ + ORTE_MAJOR_VERSION, /* MCA module major version */ + ORTE_MINOR_VERSION, /* MCA module minor version */ + ORTE_RELEASE_VERSION, /* MCA module release version */ + NULL, + NULL, + orte_notifier_syslog_component_query /* module query */ + }, + { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + } +}; + +static int orte_notifier_syslog_component_query(mca_base_module_t **module, + int *priority) +{ + *priority = 1; + *module = (mca_base_module_t *)&orte_notifier_syslog_module; + return ORTE_SUCCESS; +} diff --git a/orte/mca/notifier/syslog/notifier_syslog_module.c b/orte/mca/notifier/syslog/notifier_syslog_module.c new file mode 100644 index 00000000000..2e7c5a9f3d9 --- /dev/null +++ b/orte/mca/notifier/syslog/notifier_syslog_module.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2014 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "orte_config.h" +#include "orte/constants.h" + +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif /* HAVE_SYS_TIME_H */ +#ifdef HAVE_SYSLOG_H +#include +#endif +#ifdef HAVE_STDARG_H +#include +#endif + +#include "opal/util/show_help.h" + +#include "orte/util/error_strings.h" +#include "orte/util/name_fns.h" + +#include "orte/mca/notifier/base/base.h" +#include "notifier_syslog.h" + + +/* Static API's */ +static int init(void); +static void finalize(void); +static void mylog(orte_notifier_severity_t severity, int errcode, + const char *msg, va_list *ap); + +/* Module def */ +orte_notifier_base_module_t orte_notifier_syslog_module = { + init, + finalize, + mylog, +}; + + +static int init(void) +{ + int opts; + + opts = LOG_CONS | LOG_PID; + openlog("Open MPI Error Report:", opts, LOG_USER); + + return ORTE_SUCCESS; +} + +static void finalize(void) +{ + closelog(); +} + +static void mylog(orte_notifier_severity_t severity, int errcode, + const char *msg, va_list *ap) +{ + opal_output_verbose(5, orte_notifier_base_framework.framework_output, + "notifier:syslog:mylog function called with severity %d errcode %d and messg %s", + (int) severity, errcode, msg); + /* If there was a message, output it */ +#if defined(HAVE_VSYSLOG) + vsyslog(severity, msg, *ap); +#else + char *output; + vasprintf(&output, msg, *ap); + syslog(severity, output, NULL); + free(output); +#endif +}