Commit bf94b287 authored by Marcus Nordenberg's avatar Marcus Nordenberg

Merge branch 'rt_ini-daemonize-ability'

parents d9a86e95 cd86460c
......@@ -9,4 +9,5 @@
rls/
adm/
pwre_db
.vscode/
/*
/*
* ProviewR Open Source Process Control.
* Copyright (C) 2005-2018 SSAB EMEA AB.
*
* This file is part of ProviewR.
*
* 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
* 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
* 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
* You should have received a copy of the GNU General Public License
* along with ProviewR. If not, see <http://www.gnu.org/licenses/>
*
* Linking ProviewR statically or dynamically with other modules is
* making a combined work based on ProviewR. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
......@@ -27,18 +27,21 @@
* ProviewR Configurator, combine ProviewR with modules generated by the
* ProviewR PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of ProviewR (the version used to produce the
* combined work), being distributed under the terms of the GNU
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
#include <stdio.h>
#include <string.h>
#if defined OS_LYNX
# include <sys/wait.h>
#elif defined OS_POSIX
# include <sys/wait.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
#else
......@@ -65,23 +68,31 @@
#include "rt_errh_msg.h"
#include "rt_pwr_msg.h"
#define RT_INI_PIDFILE "/run/pwr/pwr.pid\0"
static ini_sContext *createContext (int argc, char **argv);
static int checkErrors (ini_sContext*);
static int checkErrors (ini_sContext *cp);
static pwr_tStatus events (ini_sContext *cp);
static void daemonize();
static void create_pidfile();
static pwr_tStatus interactive (int argc, char **argv, ini_sContext *cp);
static pwr_tStatus stop (int argc, char **argv, ini_sContext *cp);
static pwr_tStatus stop (ini_sContext *cp);
static void create_locks();
static void delete_locks();
static void load_backup ();
static void logChanges (ini_sContext*);
static void logCardinality (ini_sContext*);
static void logChanges (ini_sContext *cp);
static void logCardinality (ini_sContext *cp);
static pwr_tStatus restart (ini_sContext *cp);
static pwr_tStatus terminate (ini_sContext *cp);
static pwr_tStatus terminate ();
static pwr_tStatus start (ini_sContext *cp);
static void usage (char*);
static void ini_errl_cb( void *userdata, char *str, char severity,
pwr_tStatus sts, int anix, int message_type);
static void ini_errl_cb( void *userdata, char *str, char severity,
pwr_tStatus sts, int anix, int message_type);
void handle_signal(int sig, siginfo_t *si, void *ctx);
static int pid_fd = -1;
static char *pid_filename = NULL;
void set_valid_time()
{
......@@ -98,14 +109,28 @@ int main (int argc, char **argv)
cp = createContext(argc, argv);
ver_WriteVersionInfo("Proview Runtime Environment");
ver_WriteVersionInfo("ProviewR Runtime Environment");
if (cp->flags.b.restart) {
sts = interactive(argc, argv, cp);
} else if (cp->flags.b.stop) {
sts = stop(argc, argv, cp);
sts = stop(cp);
} else {
//Now lets daemonize if asked to
if (cp->flags.b.daemonize)
{
daemonize();
}
sts = start(cp);
//Now lets create the pid file before starting our endless event loop
if (cp->flags.b.daemonize)
{
create_pidfile();
}
sts = events(cp);
errh_LogInfo(&cp->log, "Ich sterbe!!");
}
......@@ -114,9 +139,7 @@ int main (int argc, char **argv)
}
static pwr_tStatus
start (
ini_sContext *cp
)
start (ini_sContext *cp)
{
pwr_tStatus sts;
char console[80];
......@@ -141,7 +164,7 @@ start (
errh_Init("pwr_ini", errh_eAnix_ini);
if ( cp->flags.b.interactive)
if ( cp->flags.b.interactive)
errh_Interactive();
mh_UtilCreateEvent();
......@@ -176,7 +199,7 @@ start (
errl_SetTerm(cp->np->ErrLogTerm);
}
/* Logfile is always $pwrp_log/pwr.log from V4.0.0 and handled by Linux log rotation */
/* Logfile is always $pwrp_log/pwr.log from V4.0.0 and handled by Linux log rotation */
char fname[256];
sprintf(fname, "$pwrp_log/pwr_%s.log", cp->nodename);
......@@ -216,7 +239,7 @@ start (
sts = redu_get_initial_state( cp->nodename, cp->busid, &state);
if ( ODD(sts)) {
cp->np->RedundancyState = state;
qcom_SetRedundancyState( state);
qcom_SetRedundancyState( state);
}
create_locks();
......@@ -235,7 +258,7 @@ start (
if (EVEN(sts)) {
errh_LogFatal(&cp->log, "net_Connect, %m", sts);
exit(sts);
}
}
qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcInit | ini_mEvent_newPlcStart);
......@@ -254,7 +277,7 @@ start (
sts = ini_SetAttributeAfterPlc(cp->aliasfile.name, cp->nodename, 0);
if (EVEN(sts) && sts != INI__FILE)
errh_LogError(&cp->log, "ini_SetAttributeAfterPlc, %m", sts);
ini_SetSystemStatus( cp, PWR__RUNNING);
errh_SetStatus( PWR__SRUN);
......@@ -265,7 +288,7 @@ static pwr_tStatus
interactive (
int argc,
char **argv,
ini_sContext *cp
ini_sContext *cp
)
{
pwr_tStatus sts;
......@@ -282,7 +305,7 @@ interactive (
if (!qcom_Init(&sts, 0, "pwr_ini_restart")) {
errh_LogFatal(&cp->log, "qcom_Init, %m", sts);
exit(sts);
}
}
qcom_CreateQ(&sts, &cp->myQ, NULL, "pwr_ini_restart");
if (EVEN(sts)) {
......@@ -301,7 +324,7 @@ interactive (
memcpy(sp, argv[i], len + 1);
sp += len + 1;
}
qid.qix = 550715;
qid.nid = 0;
put.type.b = 10;
......@@ -332,11 +355,7 @@ interactive (
}
static pwr_tStatus
stop (
int argc,
char **argv,
ini_sContext *cp
)
stop (ini_sContext *cp)
{
pwr_tStatus sts;
qcom_sQid qid;
......@@ -351,9 +370,8 @@ stop (
// errh_Interactive();
if (!qcom_Init(&sts, 0, "pwr_ini_stop")) {
// errh_LogFatal(&cp->log, "qcom_Init, %m", sts);
exit(sts);
}
}
// qcom_CreateQ(&sts, &cp->myQ, NULL, "pwr_ini_restart");
// if (EVEN(sts)) {
......@@ -372,7 +390,7 @@ stop (
// memcpy(sp, argv[i], len + 1);
// sp += len + 1;
// }
qid.qix = 550715;
qid.nid = 0;
put.type.b = 11;
......@@ -403,9 +421,7 @@ stop (
}
static pwr_tStatus
restart (
ini_sContext *cp
)
restart (ini_sContext *cp)
{
pwr_tStatus sts;
char time[24];
......@@ -463,16 +479,16 @@ restart (
qcom_WaitAnd(&sts, &cp->eventQ, &qcom_cQini, ini_mEvent_newPlcStartDone | cp->plc_sigmask, qcom_cTmoEternal);
errh_LogInfo(&cp->log, "Time critical period over, new PLC is running");
qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_swapDone);
for (pp = lst_Succ(NULL, &cp->proc_lh, &pl); pp != NULL; pp = lst_Succ(NULL, pl, &pl)) {
if ( pp->flags.m & ini_mProc_plc && pp->objectp) {
pwr_sClass_PlcProcess *plc = pp->objectp;
time_GetTime(&plc->LastChgTime);
if ( time_Dcomp(&plc->StartTime, &plc->StopTime) == 1)
time_Dsub(&plc->StallTime, &plc->StartTime, &plc->StopTime);
time_Dsub(&plc->StallTime, &plc->StartTime, &plc->StopTime);
else
plc->StallTime = pwr_cNDeltaTime;
plc->StallTime = pwr_cNDeltaTime;
time_DtoAscii(&plc->StallTime, 1, time, sizeof(time));
cp->np->RestartStallTime = plc->StallTime;
}
......@@ -487,9 +503,7 @@ restart (
}
static pwr_tStatus
terminate (
ini_sContext *cp
)
terminate ()
{
pwr_tStatus sts;
......@@ -502,7 +516,7 @@ terminate (
qcom_Exit(NULL);
/* Kill programs which until now doesn't handle qcom */
/*
/*
for (pp = lst_Succ(NULL, &cp->proc_lh, &pl); pp != NULL; pp = lst_Succ(NULL, pl, &pl)) {
if (strncmp("pwr_webmonmh", pp->proc.name, 12) == 0) {
kill(pp->proc.pid, SIGKILL);
......@@ -511,19 +525,19 @@ terminate (
kill(pp->proc.pid, SIGKILL);
}
}
*/
*/
/* Now sleep for a while */
sleep(3);
/* Unlink shared memory and semaphores */
gdb_UnlinkDb();
qdb_UnlinkDb();
delete_locks();
/* Destroy message handler semaphore */
mh_UtilDestroyEvent();
#if defined OS_POSIX
......@@ -531,12 +545,11 @@ terminate (
errl_Unlink();
#endif
exit(1);
exit(EXIT_SUCCESS);
}
static int
ask_yes_no (
ini_sContext *cp,
char *text
)
{
......@@ -548,9 +561,7 @@ ask_yes_no (
}
static int
checkErrors (
ini_sContext *cp
)
checkErrors (ini_sContext *cp)
{
if (cp->warnings == 0 && cp->errors == 0 && cp->fatals == 0)
......@@ -562,7 +573,7 @@ checkErrors (
errh_LogInfo(&cp->log, "Ignoring fatal errors, errors and warnings, continued...");
return 1;
} else {
return ask_yes_no(cp, "Do you want to continue");
return ask_yes_no("Do you want to continue");
}
}
if (cp->errors > 0) {
......@@ -571,7 +582,7 @@ checkErrors (
errh_LogInfo(&cp->log, "Ignoring errors and warnings, continued...");
return 1;
} else {
return ask_yes_no(cp, "Do you want to continue");
return ask_yes_no("Do you want to continue");
}
}
if (cp->warnings > 0) {
......@@ -580,7 +591,7 @@ checkErrors (
errh_LogInfo(&cp->log, "Ignoring warnings, continued...");
return 1;
} else {
return ask_yes_no(cp, "Do you want to continue");
return ask_yes_no("Do you want to continue");
}
}
return 1;
......@@ -605,137 +616,151 @@ createContext (int argc, char **argv)
for ( i = 1; i < argc; i++) {
if ( argv[i][0] == '-') {
int i_incr = 0;
for ( j = 1;
argv[i][j] != 0 && argv[i][j] != ' ' && argv[i][j] != ' ';
j++) {
switch ( argv[i][j]) {
case 'a':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.applfile = 1;
strcpy(cp->applfile.name, argv[i+1]);
i++;
i_incr = 1;
break;
case 'b':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.bootfile = 1;
strcpy(cp->bootfile.name, argv[i+1]);
break;
case 'c':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
strcpy(cp->console, argv[i+1]);
i++;
i_incr = 1;
break;
case 'd':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
strcpy(cp->dir, argv[i+1]);
i++;
i_incr = 1;
break;
case 'e':
cp->flags.b.ignoreError = 1;
break;
case 'f':
cp->flags.b.ignoreFatal = 1;
break;
case 'h':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.hostname = 1;
strcpy(cp->hostname, argv[i+1]);
i++;
i_incr = 1;
break;
case 'i':
cp->flags.b.interactive = 1;
break;
case 'n':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.nodename = 1;
strcpy(cp->nodename, argv[i+1]);
i++;
i_incr = 1;
break;
case 'p':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.plcfile = 1;
cp->plcfile = (ini_sFile *) calloc( 1, sizeof(ini_sFile));
cp->plcfile_cnt = 1;
strcpy(cp->plcfile[0].name, argv[i+1]);
cp->plcfile[0].logOpenFail = errh_LogInfo;
i++;
i_incr = 1;
break;
case 'q':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.busid = 1;
cp->busid = atoi(argv[i+1]);
break;
case 'r':
cp->flags.b.restart = 1;
cp->flags.b.interactive = 1;
break;
case 's':
cp->flags.b.stop = 1;
break;
case 'v':
cp->flags.b.verbose = 1;
break;
case 'w':
cp->flags.b.ignoreWarning = 1;
break;
case 'A':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.aliasfile = 1;
strcpy(cp->aliasfile.name, argv[i+1]);
i++;
i_incr = 1;
break;
case '?':
usage(argv[0]);
break;
default:
usage(argv[0]);
exit(0);
}
if ( i_incr)
break;
for ( j = 1;
argv[i][j] != 0 && argv[i][j] != ' ' && argv[i][j] != ' ';
j++) {
switch ( argv[i][j]) {
case 'a':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.applfile = 1;
strcpy(cp->applfile.name, argv[i+1]);
i++;
i_incr = 1;
break;
case 'b':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.bootfile = 1;
strcpy(cp->bootfile.name, argv[i+1]);
break;
case 'c':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
strcpy(cp->console, argv[i+1]);
i++;
i_incr = 1;
break;
case 'd':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
strcpy(cp->dir, argv[i+1]);
i++;
i_incr = 1;
break;
case 'e':
cp->flags.b.ignoreError = 1;
break;
case 'f':
cp->flags.b.ignoreFatal = 1;
break;
case 'h':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.hostname = 1;
strcpy(cp->hostname, argv[i+1]);
i++;
i_incr = 1;
break;
case 'i':
cp->flags.b.interactive = 1;
break;
case 'n':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.nodename = 1;
strcpy(cp->nodename, argv[i+1]);
i++;
i_incr = 1;
break;
case 'p':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.plcfile = 1;
cp->plcfile = (ini_sFile *) calloc( 1, sizeof(ini_sFile));
cp->plcfile_cnt = 1;
strcpy(cp->plcfile[0].name, argv[i+1]);
cp->plcfile[0].logOpenFail = errh_LogInfo;
i++;
i_incr = 1;
break;
case 'q':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.busid = 1;
cp->busid = atoi(argv[i+1]);
break;
case 'r':
cp->flags.b.restart = 1;
cp->flags.b.interactive = 1;
break;
case 's':
cp->flags.b.stop = 1;
break;
case 'v':
cp->flags.b.verbose = 1;
break;
case 'w':
cp->flags.b.ignoreWarning = 1;
break;
case 'A':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.aliasfile = 1;
strcpy(cp->aliasfile.name, argv[i+1]);
i++;
i_incr = 1;
break;
case 'D':
cp->flags.b.daemonize = 1;
break;
case 'P':
if ( i + 1 >= argc ||
!(argv[i][j+1] == ' ' || argv[i][j+1] != ' ')) {
usage( argv[0]);
exit(0);
}
cp->flags.b.daemonize = 1;
pid_filename = strdup(argv[i+1]);
i++;
i_incr = 1;
break;
case '?':
usage(argv[0]);
break;
default:
usage(argv[0]);
exit(0);
}
if ( i_incr)
break;
}
}
}
......@@ -773,15 +798,15 @@ usage (
fprintf(stderr, " -v : verbose\n");
fprintf(stderr, " -w : ignore warnings\n");
fprintf(stderr, " -A arg: use 'arg' as alias file\n");
fprintf(stderr, " -D : Daemonize rt_ini. Default PID file is /run/pwr/pwr.pid\n");
fprintf(stderr, " -p : PID file, implies -D\n");
fprintf(stderr, " -H arg: use 'arg' as hostname\n");
fprintf(stderr, " -N arg: use 'arg' as nodename\n");
exit(1);
}
static void
logChanges (
ini_sContext *cp
)
logChanges (ini_sContext *cp)
{
lst_sEntry *vl;
lst_sEntry *ol;
......@@ -824,23 +849,19 @@ logChanges (
}
static void
logCardinality (
ini_sContext *cp
)
logCardinality (ini_sContext *cp)
{
lst_sEntry *vl;
ivol_sVolume *vp;
errh_LogInfo(&cp->log, "Cardinality: %d, bodysize: %d\n", cp->node.cardinality, cp->node.bodySize);
errh_LogInfo(&cp->log, "Cardinality: %d, bodysize: %d\n", cp->node.cardinality, cp->node.bodySize);
for (vp = lst_Succ(NULL, &cp->vol_lh, &vl); vp != NULL; vp = lst_Succ(NULL, vl, &vl))
errh_LogInfo(&cp->log, "Volume: %s, id: %d, cardinality: %d, bodysize: %d\n", vp->volume.name, vp->vid,
vp->volume.cardinality, vp->volume.rbodySize);
}
static pwr_tStatus
events (
ini_sContext *cp
)
events (ini_sContext *cp)
{
lst_sEntry *pl;
ini_sProc *pp;
......@@ -868,13 +889,13 @@ events (
get.data = NULL;
qcom_Get(&sts, &cp->myQ, &get, tmo_ms);
/* Request for termination ?? */
if (sts != QCOM__TMO && sts != QCOM__QEMPTY && get.type.b == 11) {
sts = terminate(cp);
return sts;
}
/* Request for restart */
if (sts != QCOM__TMO && sts != QCOM__QEMPTY && get.data != NULL) {
int len, i, argc, totlen;
......@@ -882,27 +903,27 @@ events (
ini_sContext *ncp;
for (argc = 0, s = get.data, totlen = 0; totlen < get.size; argc++) {
len = strlen(s);
s += len + 1;
totlen += len + 1;
len = strlen(s);
s += len + 1;
totlen += len + 1;
}
argv = (char **) calloc(sizeof(void*), argc);
for (i = 0, s = get.data; i < argc; i++) {
len = strlen(s);
argv[i] = s;
s += len + 1;
len = strlen(s);
argv[i] = s;
s += len + 1;
}
ncp = createContext(argc, argv);
if (ncp != NULL) {
ncp->log.put.type.b = 10;
ncp->log.put.type.s = 1;
ncp->log.send = 1;
ncp->log.put.reply = cp->myQ;
ncp->log.logQ = get.reply;
ncp->eventQ = cp->eventQ;
ncp->yourQ = get.reply;
restart(ncp);
free(ncp);
ncp->log.put.type.b = 10;
ncp->log.put.type.s = 1;
ncp->log.send = 1;
ncp->log.put.reply = cp->myQ;
ncp->log.logQ = get.reply;
ncp->eventQ = cp->eventQ;
ncp->yourQ = get.reply;
restart(ncp);
free(ncp);
}
free(argv);
qcom_Free(NULL, get.data);
......@@ -913,16 +934,16 @@ events (
pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
if (pid == 0) continue;
if (pid == last_pid) break;
for (pp = lst_Succ(NULL, &cp->proc_lh, &pl); pp != NULL; pp = lst_Succ(NULL, pl, &pl)) {
if (pp->proc.pid == pid) {
errh_LogInfo(&cp->log, "Process %s exited with status %d", pp->proc.name, status);
break;
errh_LogInfo(&cp->log, "Process %s exited with status %d", pp->proc.name, status);
break;
}
}
#endif
}
return INI__SUCCESS;
}
......@@ -976,8 +997,8 @@ load_backup ()
int i;
pwr_sClass_IOHandler *iop;
pwr_sAttrRef aref;
sts = io_get_iohandler_object(&iop, NULL);
sts = io_get_iohandler_object(&iop, NULL);
if (EVEN(sts)) {
errh_Error("io_get_iohandler_object, %m", sts);
return;
......@@ -1188,8 +1209,8 @@ load_backup ()
ini_sRestoreSig *rsav = calloc( sizeof(ini_sRestoreSig), iop->AvCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Av, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Av, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Av, &aref, &aref)) {
if ( i >= iop->AvCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsav[i].op.av);
......@@ -1202,12 +1223,12 @@ load_backup ()
rsav[i].validx = rsav[i].op.av->ValueIndex;
i++;
}
ini_sRestoreSig *rsdv = calloc( sizeof(ini_sRestoreSig), iop->DvCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Dv, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Dv, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Dv, &aref, &aref)) {
if ( i >= iop->DvCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsdv[i].op.dv);
......@@ -1220,12 +1241,12 @@ load_backup ()
rsdv[i].validx = rsdv[i].op.dv->ValueIndex;
i++;
}
ini_sRestoreSig *rsiv = calloc( sizeof(ini_sRestoreSig), iop->IvCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Iv, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Iv, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Iv, &aref, &aref)) {
if ( i >= iop->IvCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsiv[i].op.iv);
......@@ -1238,12 +1259,12 @@ load_backup ()
rsiv[i].validx = rsiv[i].op.iv->ValueIndex;
i++;
}
ini_sRestoreSig *rsatv = calloc( sizeof(ini_sRestoreSig), iop->ATvCount);
i = 1;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_ATv, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_ATv, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_ATv, &aref, &aref)) {
if ( i >= iop->ATvCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsatv[i].op.atv);
......@@ -1256,12 +1277,12 @@ load_backup ()
rsatv[i].validx = rsatv[i].op.atv->ValueIndex;
i++;
}
ini_sRestoreSig *rsdtv = calloc( sizeof(ini_sRestoreSig), iop->DTvCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_DTv, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_DTv, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_DTv, &aref, &aref)) {
if ( i >= iop->DTvCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsdtv[i].op.dtv);
......@@ -1274,12 +1295,12 @@ load_backup ()
rsdtv[i].validx = rsdtv[i].op.dtv->ValueIndex;
i++;
}
ini_sRestoreSig *rssv = calloc( sizeof(ini_sRestoreSig), iop->SvCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Sv, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Sv, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Sv, &aref, &aref)) {
if ( i >= iop->SvCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rssv[i].op.sv);
......@@ -1292,12 +1313,12 @@ load_backup ()
rssv[i].validx = rssv[i].op.sv->ValueIndex;
i++;
}
ini_sRestoreSig *rsai = calloc( sizeof(ini_sRestoreSig), iop->AiCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Ai, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Ai, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Ai, &aref, &aref)) {
if ( i >= iop->AiCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsai[i].op.ai);
......@@ -1310,12 +1331,12 @@ load_backup ()
rsai[i].validx = rsai[i].op.ai->ValueIndex;
i++;
}
ini_sRestoreSig *rsao = calloc( sizeof(ini_sRestoreSig), iop->AoCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Ao, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Ao, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Ao, &aref, &aref)) {
if ( i >= iop->AoCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsao[i].op.ao);
......@@ -1328,12 +1349,12 @@ load_backup ()
rsao[i].validx = rsao[i].op.ao->ValueIndex;
i++;
}
ini_sRestoreSig *rsii = calloc( sizeof(ini_sRestoreSig), iop->IiCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Ii, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Ii, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Ii, &aref, &aref)) {
if ( i >= iop->IiCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsii[i].op.ii);
......@@ -1346,12 +1367,12 @@ load_backup ()
rsii[i].validx = rsii[i].op.ii->ValueIndex;
i++;
}
ini_sRestoreSig *rsio = calloc( sizeof(ini_sRestoreSig), iop->IoCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Io, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Io, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Io, &aref, &aref)) {
if ( i >= iop->IoCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsio[i].op.io);
......@@ -1364,12 +1385,12 @@ load_backup ()
rsio[i].validx = rsio[i].op.io->ValueIndex;
i++;
}
ini_sRestoreSig *rsdi = calloc( sizeof(ini_sRestoreSig), iop->DiCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Di, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Di, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Di, &aref, &aref)) {
if ( i >= iop->DiCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsdi[i].op.di);
......@@ -1382,12 +1403,12 @@ load_backup ()
rsdi[i].validx = rsdi[i].op.di->ValueIndex;
i++;
}
ini_sRestoreSig *rsdo = calloc( sizeof(ini_sRestoreSig), iop->DoCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Do, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Do, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Do, &aref, &aref)) {
if ( i >= iop->DoCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsdo[i].op.dox);
......@@ -1400,13 +1421,13 @@ load_backup ()
rsdo[i].validx = rsdo[i].op.dox->ValueIndex;
i++;
}
ini_sRestoreSig *rsco = calloc( sizeof(ini_sRestoreSig), iop->CoCount);
pwr_tInt32 **rscoa = calloc( sizeof(pwr_tInt32*), iop->CoCount);
i = 0;
for ( sts = gdh_GetClassListAttrRef(pwr_cClass_Co, &aref);
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Co, &aref, &aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef(pwr_cClass_Co, &aref, &aref)) {
if ( i >= iop->CoCount) break;
sts = gdh_AttrRefToPointer( &aref, (pwr_tAddress *)&rsco[i].op.co);
......@@ -1420,7 +1441,7 @@ load_backup ()
rscoa[i] = rsco[i].op.co->AbsValue;
i++;
}
sts = bck_LoadBackup();
if (EVEN(sts)) {
......@@ -1542,7 +1563,7 @@ load_backup ()
}
static void ini_errl_cb( void *userdata, char *str, char severity, pwr_tStatus sts, int anix,
int message_type)
int message_type)
{
ini_sContext *cp = (ini_sContext *) userdata;
......@@ -1558,17 +1579,17 @@ static void ini_errl_cb( void *userdata, char *str, char severity, pwr_tStatus s
switch ( severity) {
case 'S':
case 'I':
sts = PWR__SRVINFO;
break;
sts = PWR__SRVINFO;
break;
case 'E':
sts = PWR__SRVERROR;
break;
sts = PWR__SRVERROR;
break;
case 'W':
sts = PWR__SRVWARNING;
break;
sts = PWR__SRVWARNING;
break;
case 'F':
sts = PWR__SRVFATAL;
break;
sts = PWR__SRVFATAL;
break;
}
}
cp->np->ProcMsgSeverity[anix-1] = sts;
......@@ -1580,3 +1601,148 @@ static void ini_errl_cb( void *userdata, char *str, char severity, pwr_tStatus s
break;
}
}
/**
* @brief create_pidfile Creates a pidfile for the process for things like systemd to keep track of.
*/
static void create_pidfile()
{
char str[256];
if (pid_filename == NULL)
pid_filename = strdup(RT_INI_PIDFILE);
pid_fd = open(pid_filename, O_RDWR|O_CREAT, 0640);
if (pid_fd < 0)
{
exit(EXIT_FAILURE);
}
if (lockf(pid_fd, F_TLOCK, 0) < 0)
{
exit(EXIT_FAILURE);
}
sprintf(str, "%d\n", getpid());
write(pid_fd, str, strlen(str));
}
/**
* @brief daemonize Forks twice in order to detach itself properly. Closes all file descriptors currently open.
*/
static void daemonize() {
pid_t pid = 0;
struct sigaction act;
// First fork
pid = fork();
if (pid < 0) exit(EXIT_FAILURE);
// Let the parent exit
if (pid > 0) exit(EXIT_SUCCESS);
//Set the process to be session leader
if (setsid() < 0) exit(EXIT_FAILURE);
//Ignore any signals from children
signal(SIGCHLD, SIG_IGN);
//Second fork
pid = fork();
if (pid < 0) exit(EXIT_FAILURE);
// Bye bye parent
if (pid > 0) exit(EXIT_SUCCESS);
umask(002);
chdir("/");
//Close all file descriptors
for (int fd = sysconf(_SC_OPEN_MAX); fd > 0; fd--)
close(fd);
//Reopen some fds
stdin = fopen("/dev/null", "r");
stdout = fopen("/dev/null", "w+");
stderr = fopen("/dev/null", "w+");
// Register signal handler
act.sa_handler = NULL;
act.sa_sigaction = handle_signal;
act.sa_flags |= SA_SIGINFO;
if ((sigemptyset(&act.sa_mask) == -1) || (sigaction(SIGTERM, &act, NULL) == -1) || (sigaction(SIGHUP, &act, NULL) == -1))
{
perror("Could not set up signal handlers for rt_ini");
}
//signal(SIGTERM, handle_signal);
//signal(SIGINT, handle_signal);
}
//void handle_signal(int sig)
//{
// //pwr_tStatus sts;
// switch (sig) {
// case SIGTERM:
// {
// errh_LogInfo(&cp->log, "SIGNAL CAUGHT (%d). Exiting!\n", sig, cp->node.bodySize);
// stop();
// //running = 0;
// if (cp->flags.b.daemonize)
// {
// if (pid_fd != -1)
// {
// lockf(pid_fd, F_ULOCK, 0);
// close(pid_fd);
// }
// if (pid_filename != NULL)
// {
// unlink(pid_filename);
// }
// }
// }
// default:
// // Noop
// break;
// }
//}
/**
* @brief handle_signal
* @param sig
* @param si
* @param ctx
*/
void handle_signal(int sig, siginfo_t *si, void *ctx)
{
ini_sContext *cp = (ini_sContext*)ctx;
switch (sig) {
case SIGTERM:
errh_LogInfo(&cp->log, "SIGNAL CAUGHT (%d). Exiting!\n", sig, cp->node.bodySize);
stop(cp);
//running = 0;
if (cp->flags.b.daemonize)
{
if (pid_fd != -1)
{
lockf(pid_fd, F_ULOCK, 0);
close(pid_fd);
}
if (pid_filename != NULL)
{
unlink(pid_filename);
}
}
break;
case SIGHUP:
errh_LogInfo(&cp->log, "SIGNAL CAUGHT (%d). Restarting!\n", sig, cp->node.bodySize);
//TODO restart :)
break;
default:
// Noop
break;
}
}
/*
/*
* ProviewR Open Source Process Control.
* Copyright (C) 2005-2018 SSAB EMEA AB.
*
* This file is part of ProviewR.
*
* 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
* 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
* 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
* You should have received a copy of the GNU General Public License
* along with ProviewR. If not, see <http://www.gnu.org/licenses/>
*
* Linking ProviewR statically or dynamically with other modules is
* making a combined work based on ProviewR. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
......@@ -27,10 +27,10 @@
* ProviewR Configurator, combine ProviewR with modules generated by the
* ProviewR PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of ProviewR (the version used to produce the
* combined work), being distributed under the terms of the GNU
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
......@@ -57,7 +57,8 @@ typedef union {
pwr_Bits( verbose , 1),
pwr_Bits( restart , 1),
pwr_Bits( stop , 1),
pwr_Bits( fill_0 , 2),,,
pwr_Bits( daemonize , 1),
pwr_Bits( fill_0 , 1),,
pwr_Bits( interactive , 1),
pwr_Bits( busid , 1),
......@@ -82,6 +83,7 @@ typedef union {
#define ini_mContext_verbose pwr_Bit(3)
#define ini_mContext_restart pwr_Bit(4)
#define ini_mContext_stop pwr_Bit(5)
#define ini_mContext_daemonize pwr_Bit(6)
#define ini_mContext_interactive pwr_Bit(8)
#define ini_mContext_busid pwr_Bit(9)
......@@ -97,7 +99,7 @@ typedef union {
#define ini_mContext_ (~ini_mContext__)
} ini_mContext;
typedef union {
pwr_tBitMask m;
pwr_32Bits (
......@@ -130,7 +132,7 @@ typedef union {
#define ini_mProc_ (~ini_mProc__)
} ini_mProc;
typedef struct {
char name[256];
int *errcount;
......@@ -199,14 +201,14 @@ pwr_tBoolean ini_CreateDb (pwr_tStatus*, ini_sContext*);
pwr_tBoolean ini_DecodeBodies (pwr_tStatus*, ini_sContext*, pwr_tBoolean);
pwr_tBoolean ini_FreeBodies (pwr_tStatus*, ini_sContext*, pwr_tBoolean);
pwr_tBoolean ini_IterVolumes (pwr_tStatus*, ini_sContext*,
pwr_tBoolean (*func)(pwr_tStatus*, ini_sContext*, ivol_sVolume*));
pwr_tBoolean (*func)(pwr_tStatus*, ini_sContext*, ivol_sVolume*));
char * ini_LoadDirectory (pwr_tStatus*, ini_sContext*);
pwr_tBoolean ini_LoadNode (pwr_tStatus*, ini_sContext*);
pwr_tBoolean ini_LoadVolume (pwr_tStatus*, ini_sContext*, ivol_sVolume*);
FILE *ini_OpenFile (pwr_tStatus*, ini_sContext*, ini_sFile*);
ini_sProc *ini_ProcInsert (pwr_tStatus*, ini_sContext*, char*, char*, int, int, char*, int, int, pwr_tCid, char*, void*);
void ini_ProcIter (pwr_tStatus*, ini_sContext*, int, int,
void (*func) (pwr_tStatus*, ini_sContext*, ini_sProc*));
void (*func) (pwr_tStatus*, ini_sContext*, ini_sProc*));
void ini_ProcLoad (pwr_tStatus*, ini_sContext*, ini_sProc*);
void ini_ProcStart (pwr_tStatus*, ini_sContext*, ini_sProc*);
void ini_ProcPrio (pwr_tStatus*, ini_sContext*, ini_sProc*);
......
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