implement IPC messaging with queue loop
This commit is contained in:
parent
1338bd660b
commit
16d950f98d
@ -2,7 +2,7 @@ INCLUDES=${gammu_CFLAGS}
|
|||||||
yasnd_LDADD = ${libconfuse_LIBS}
|
yasnd_LDADD = ${libconfuse_LIBS}
|
||||||
yasnd_LDADD += ${gammu_LIBS}
|
yasnd_LDADD += ${gammu_LIBS}
|
||||||
bin_PROGRAMS = yasnd
|
bin_PROGRAMS = yasnd
|
||||||
yasnd_SOURCES = yasnd.c yasnd-gammu.c
|
yasnd_SOURCES = yasnd.c yasnd-gammu.c yasnd-ipc.c
|
||||||
|
|
||||||
distclean-local:
|
distclean-local:
|
||||||
rm -rf aclocal.m4 autom4te.cache depcomp install-sh missing configure Makefile.in config.h* &>/dev/null
|
rm -rf aclocal.m4 autom4te.cache depcomp install-sh missing configure Makefile.in config.h* &>/dev/null
|
||||||
|
80
yasnd-ipc.c
Normal file
80
yasnd-ipc.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
|
|
||||||
|
#include "yasnd.h"
|
||||||
|
|
||||||
|
pid_t ipc_clone_pid;
|
||||||
|
|
||||||
|
int open_queue()
|
||||||
|
{
|
||||||
|
key_t keyval=ftok(".",'m');
|
||||||
|
int qid;
|
||||||
|
if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1)
|
||||||
|
{
|
||||||
|
log_event("Error opening/creating IPC message queue");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return qid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_message(int qid, mymsgbuf* qbuf)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
/* The length is essentially the size of the structure minus sizeof(mtype) */
|
||||||
|
int length = sizeof(mymsgbuf) - sizeof(long);
|
||||||
|
|
||||||
|
if((result = msgsnd( qid, qbuf, length, 0)) == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_message(int qid, mymsgbuf* qbuf, long type)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int length = sizeof(mymsgbuf) - sizeof(long);
|
||||||
|
if((result = msgrcv( qid, qbuf, length, type, 0)) == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_queue( int qid )
|
||||||
|
{
|
||||||
|
if( msgctl(qid, IPC_RMID, 0) == -1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_queue_loop()
|
||||||
|
{
|
||||||
|
// set default signal handlers
|
||||||
|
signal(SIGTERM,SIG_DFL);
|
||||||
|
signal(SIGHUP,SIG_DFL);
|
||||||
|
//
|
||||||
|
mymsgbuf qbuf;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int result=read_message(qid, &qbuf, 1);
|
||||||
|
if (result==-1)
|
||||||
|
{
|
||||||
|
log_event("Error: finishing IPC loop process...");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char dbg_txt[150];
|
||||||
|
sprintf(dbg_txt,"Read IPC message - Type: %ld Text: %s", qbuf.mtype, qbuf.mtext);
|
||||||
|
log_debug(dbg_txt,DEBUG_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_init()
|
||||||
|
{
|
||||||
|
qid = open_queue();
|
||||||
|
unsigned char ipc_child_stack[16384];
|
||||||
|
ipc_clone_pid=clone(ipc_queue_loop,ipc_child_stack+8192,CLONE_VM,NULL);
|
||||||
|
}
|
36
yasnd.c
36
yasnd.c
@ -8,7 +8,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <confuse.h>
|
#include <confuse.h>
|
||||||
|
|
||||||
#include "yasnd.h"
|
#include "yasnd.h"
|
||||||
@ -16,6 +15,7 @@
|
|||||||
cfg_t *cfg; // pointer to configuration structure
|
cfg_t *cfg; // pointer to configuration structure
|
||||||
host_decl* hosts=NULL; // structure with hosts' definitions
|
host_decl* hosts=NULL; // structure with hosts' definitions
|
||||||
int hosts_count=0; // count of hosts
|
int hosts_count=0; // count of hosts
|
||||||
|
int qid=-1; // IPC queue id
|
||||||
int debug_flag=0;
|
int debug_flag=0;
|
||||||
bool sms_send_enable=false; // send or not send alerts via SMS
|
bool sms_send_enable=false; // send or not send alerts via SMS
|
||||||
char* phone_device=NULL; // phone device for gammu, for example: "/dev/ttyACM0"
|
char* phone_device=NULL; // phone device for gammu, for example: "/dev/ttyACM0"
|
||||||
@ -109,7 +109,6 @@ void init()
|
|||||||
}
|
}
|
||||||
// initialize gammu structures
|
// initialize gammu structures
|
||||||
gammu_init();
|
gammu_init();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_host(int num,host_decl* host)
|
void check_host(int num,host_decl* host)
|
||||||
@ -121,6 +120,10 @@ void check_host(int num,host_decl* host)
|
|||||||
}
|
}
|
||||||
// If pid == 0, then we are in the child
|
// If pid == 0, then we are in the child
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
|
// Set default signal handlers
|
||||||
|
signal(SIGTERM, SIG_DFL);
|
||||||
|
signal(SIGHUP, SIG_DFL);
|
||||||
|
//
|
||||||
char tmp[50];
|
char tmp[50];
|
||||||
sprintf(tmp, "Pinging host %s", host->hostname);
|
sprintf(tmp, "Pinging host %s", host->hostname);
|
||||||
log_debug(tmp,DEBUG_BASE);
|
log_debug(tmp,DEBUG_BASE);
|
||||||
@ -205,6 +208,10 @@ void signal_handler(int signum)
|
|||||||
{
|
{
|
||||||
void free_resources()
|
void free_resources()
|
||||||
{
|
{
|
||||||
|
// Stop IPC loop and remove IPC queue
|
||||||
|
kill(ipc_clone_pid,SIGTERM);
|
||||||
|
waitpid(ipc_clone_pid,NULL,__WCLONE);
|
||||||
|
remove_queue(qid);
|
||||||
// free config structure
|
// free config structure
|
||||||
cfg_free(cfg);
|
cfg_free(cfg);
|
||||||
// free gammu structure
|
// free gammu structure
|
||||||
@ -224,6 +231,8 @@ void signal_handler(int signum)
|
|||||||
|
|
||||||
// free all resources
|
// free all resources
|
||||||
free_resources();
|
free_resources();
|
||||||
|
// Init IPC loop again
|
||||||
|
ipc_init();
|
||||||
// run init again
|
// run init again
|
||||||
init();
|
init();
|
||||||
// sleep 5 seconds and unlock Main Loop
|
// sleep 5 seconds and unlock Main Loop
|
||||||
@ -234,8 +243,13 @@ void signal_handler(int signum)
|
|||||||
if (signum==SIGTERM)
|
if (signum==SIGTERM)
|
||||||
{
|
{
|
||||||
log_event("SIGTERM captured, daemon stopping");
|
log_event("SIGTERM captured, daemon stopping");
|
||||||
|
// close log decriptor
|
||||||
closelog();
|
closelog();
|
||||||
free_resources(); // free all other resources
|
// free resources
|
||||||
|
free_resources();
|
||||||
|
// remove IPC message queue
|
||||||
|
remove_queue(qid);
|
||||||
|
//
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,21 +292,25 @@ int main(void) {
|
|||||||
close(STDOUT_FILENO);
|
close(STDOUT_FILENO);
|
||||||
close(STDERR_FILENO);
|
close(STDERR_FILENO);
|
||||||
|
|
||||||
// Set signal handlers
|
// initialize IPC queue and create process
|
||||||
signal(SIGTERM, signal_handler);
|
// that will watch for new messages in it
|
||||||
signal(SIGHUP, signal_handler);
|
ipc_init();
|
||||||
|
|
||||||
// Init apropriate structures
|
// Init apropriate structures
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
// Set signal handlers
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
signal(SIGHUP, signal_handler);
|
||||||
|
|
||||||
/* The Main Loop */
|
/* The Main Loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!loop_locked)
|
if (!loop_locked)
|
||||||
{
|
{
|
||||||
loop_function();
|
loop_function();
|
||||||
// sleep(60); /* wait 60 seconds */
|
sleep(60); /* wait 60 seconds */
|
||||||
log_event("Exiting");
|
// log_event("Exiting");
|
||||||
exit(EXIT_SUCCESS);
|
// exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
30
yasnd.h
30
yasnd.h
@ -5,17 +5,14 @@
|
|||||||
#define DEBUG_BASE 1
|
#define DEBUG_BASE 1
|
||||||
#define DEBUG_ALL 2
|
#define DEBUG_ALL 2
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gammu.h>
|
#include <gammu.h>
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
// External functions
|
// Structure, that described single checked host
|
||||||
extern void log_event(const char *message);
|
|
||||||
extern void log_debug(const char *message,int verbosity);
|
|
||||||
extern bool check_gammu_error(GSM_Error err);
|
|
||||||
extern bool gammu_init();
|
|
||||||
extern bool gammu_send_sms(const char* message);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* hostname; // address of host
|
char* hostname; // address of host
|
||||||
pid_t helper_pid; // pid of helper('pinger') child process
|
pid_t helper_pid; // pid of helper('pinger') child process
|
||||||
@ -23,6 +20,23 @@ typedef struct {
|
|||||||
bool alert_sent; // variable, that changed when host goes online/offline
|
bool alert_sent; // variable, that changed when host goes online/offline
|
||||||
} host_decl;
|
} host_decl;
|
||||||
|
|
||||||
|
// Structure, that described single IPC message
|
||||||
|
typedef struct {
|
||||||
|
long mtype; /* Message type */
|
||||||
|
char mtext[100];
|
||||||
|
} mymsgbuf;
|
||||||
|
|
||||||
|
// External functions
|
||||||
|
extern void log_event(const char *message);
|
||||||
|
extern void log_debug(const char *message,int verbosity);
|
||||||
|
extern void* allocate_memory(int bytes);
|
||||||
|
extern bool check_gammu_error(GSM_Error err);
|
||||||
|
extern bool gammu_init();
|
||||||
|
extern bool gammu_send_sms(const char* message);
|
||||||
|
extern void ipc_init();
|
||||||
|
extern int remove_queue(int qid);
|
||||||
|
extern int send_message(int qid, mymsgbuf* qbuf);
|
||||||
|
|
||||||
// External variables
|
// External variables
|
||||||
extern int hosts_count; // count of hosts
|
extern int hosts_count; // count of hosts
|
||||||
extern int debug_flag;
|
extern int debug_flag;
|
||||||
@ -32,5 +46,7 @@ extern char* recipient_number;
|
|||||||
extern char* phone_device; // phone device for gammu, for example: "/dev/ttyACM0"
|
extern char* phone_device; // phone device for gammu, for example: "/dev/ttyACM0"
|
||||||
extern char* phone_model; // gammu phone model, for example: "at"
|
extern char* phone_model; // gammu phone model, for example: "at"
|
||||||
extern char* phone_connection; // gammu phone connection type, for example: "at"
|
extern char* phone_connection; // gammu phone connection type, for example: "at"
|
||||||
|
extern int qid;
|
||||||
|
extern pid_t ipc_clone_pid;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user