Commit b0ee2d93 authored by Marcus Nordenberg's avatar Marcus Nordenberg Committed by Esteban Blanc

rt_post: Bugfixes + asynchronous calls

* Fixed bug where sending only happened
  if both sms and email were chosen.
* Calls are now asynchronous.
* We can now properly wait for DSN's from the sending service and
  thus reflect the actual status of the sending of the mail/sms.

(cherry picked from commit 9d8e24a9b8d102a37ad5b35ff1734c3e2d5208fb)
parent 0a68b8dc
......@@ -35,6 +35,10 @@
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <map>
#include "co_cdh.h"
#include "co_dcli.h"
......@@ -52,6 +56,7 @@
#include "rt_qcom_msg.h"
static rt_post* post = 0;
std::map<pid_t, pwr_ePostType> rt_post::dispatchProcesses;
typedef union alau_Event ala_uEvent;
union alau_Event {
......@@ -123,8 +128,75 @@ void rt_post::open()
conf->Status = PWR__SRUN;
}
int rt_post::check_dispatch()
{
int wstatus;
pid_t wpid;
for (auto proc_it = dispatchProcesses.begin(); proc_it != dispatchProcesses.end();)
{
wpid = waitpid(proc_it->first, &wstatus, WNOHANG);
if (wpid > 0)
{
if (WEXITSTATUS(wstatus))
{
errh_Error(
"Unable to send mail/sms to recipient. Check configuration!");
}
else
{
try
{
switch (proc_it->second)
{
case pwr_ePostType_Mail:
post->conf->SentEmail++;
break;
case pwr_ePostType_SMS:
post->conf->SentSMS++;
break;
default:
errh_Warning("Unknown rt_post dispatch process!");
}
proc_it = dispatchProcesses.erase(proc_it);
continue;
}
catch (std::exception& e)
{
errh_Warning("Error checking rt_post dispatch process");
}
}
}
else if (wpid == -1)
{
// Pretty much implies ECHILD since WNOHANG is used and options are correct...
// If all is good, this would never happen though...
// Clear dispatch list since we don't have any children to tend to anyways...
dispatchProcesses.clear();
return -1;
}
proc_it++;
}
return 0;
}
void rt_post::close()
{
short unsigned int retries_left = 10;
// Wait for any children still trying to send mail/sms...
while (!dispatchProcesses.empty() && retries_left--)
{
// Break in the odd event of an error upon waiting for children. -1 indicate an error...
// Otherwise check again after a while. If the mail/sms service is having problems this can take a while.
// Abort after 10 retries
if (check_dispatch() < 0)
break;
sleep(1);
}
mh_OutunitDisconnect();
}
......@@ -132,6 +204,11 @@ void rt_post::scan()
{
pwr_tStatus sts = 1;
// Check if any sending processes have finished.
// Don't care about the return value...
if (!dispatchProcesses.empty())
check_dispatch();
while (ODD(sts))
sts = mh_OutunitReceive();
......@@ -185,6 +262,8 @@ pwr_tStatus rt_post::mh_return_bc(mh_sReturn* MsgP)
}
pwr_tStatus rt_post::mh_alarm_bc(mh_sMessage* MsgP)
{
pid_t cpid;
ala_uEvent* event = (ala_uEvent*)MsgP;
int sts;
char str[256];
......@@ -200,8 +279,8 @@ pwr_tStatus rt_post::mh_alarm_bc(mh_sMessage* MsgP)
if (!post || post->conf->Disable)
return 1;
if (!(event->Info.EventFlags & pwr_mEventFlagsMask_Email)
|| !(event->Info.EventFlags & pwr_mEventFlagsMask_SMS))
if (!((event->Info.EventFlags & pwr_mEventFlagsMask_Email) ||
(event->Info.EventFlags & pwr_mEventFlagsMask_SMS)))
return 1;
// Skip events older than 10 minutes
......@@ -219,8 +298,8 @@ pwr_tStatus rt_post::mh_alarm_bc(mh_sMessage* MsgP)
else
post->email_register(&event->Info.Id);
}
if (event->Info.EventFlags & pwr_mEventFlagsMask_SMS) {
if (event->Info.EventFlags & pwr_mEventFlagsMask_SMS)
{
if (post->sms_check(&event->Info.Id))
return 1;
else
......@@ -281,8 +360,20 @@ pwr_tStatus rt_post::mh_alarm_bc(mh_sMessage* MsgP)
if (post->conf->Options & pwr_mPostOptionsMask_Log)
errh_Info("Email: %s", cmd);
system(cmd);
post->conf->SentEmail++;
// Fork and execute command
if ((cpid = fork()) == -1)
{
errh_Warning("Unable to fork a process for sending Email!");
}
else if (cpid == 0)
{
execl("/bin/sh", "sh", "-c", cmd, (char*)0);
_exit(EXIT_FAILURE);
}
else
{
dispatchProcesses.insert(std::make_pair(cpid, pwr_ePostType_Mail));
}
}
if (event->Info.EventFlags & pwr_mEventFlagsMask_SMS
&& !streq(post->conf->SMS_Cmd, "")) {
......@@ -297,8 +388,20 @@ pwr_tStatus rt_post::mh_alarm_bc(mh_sMessage* MsgP)
if (post->conf->Options & pwr_mPostOptionsMask_Log)
errh_Info("SMS: %s", cmd);
system(cmd);
post->conf->SentSMS++;
// Fork and execute command
if ((cpid = fork()) == -1)
{
errh_Warning("Unable to fork a process for sending SMS!");
}
else if (cpid == 0)
{
execl("/bin/sh", "sh", "-c", cmd, (char*)0);
_exit(EXIT_FAILURE);
}
else
{
dispatchProcesses.insert(std::make_pair(cpid, pwr_ePostType_SMS));
}
}
}
return 1;
......
......@@ -37,11 +37,18 @@
#ifndef rt_post_h
#define rt_post_h
#include <map>
#include "rt_mh.h"
#include "rt_mh_outunit.h"
#include "co_user.h"
#include "pwr_baseclasses.h"
typedef enum _pwr_ePostType
{
pwr_ePostType_Mail,
pwr_ePostType_SMS
} pwr_ePostType;
/*! \file rt_post.h
\brief Contains the rt_post class. */
/*! \addtogroup rt */
......@@ -64,6 +71,7 @@ class rt_post {
void sms_register(mh_sEventId* id);
int email_check(mh_sEventId* id);
int sms_check(mh_sEventId* id);
int check_dispatch();
void format_sms_text(mh_sMessage* MsgP, char* text, unsigned int size);
void format_email_text(mh_sMessage* MsgP, char* text, unsigned int size);
......@@ -75,6 +83,7 @@ class rt_post {
static pwr_tStatus mh_info_bc(mh_sMessage* MsgP);
static pwr_tStatus mh_clear_alarmlist_bc(pwr_tNodeIndex nix);
static pwr_tStatus mh_clear_blocklist_bc(pwr_tNodeIndex nix);
static std::map<pid_t, pwr_ePostType> dispatchProcesses;
double scan_time;
pwr_sClass_PostConfig* conf;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment