Commit cd86460c authored by Marcus Nordenberg's avatar Marcus Nordenberg

add rt_ini daemonize ability

parent d9a86e95
...@@ -9,4 +9,5 @@ ...@@ -9,4 +9,5 @@
rls/ rls/
adm/ adm/
pwre_db pwre_db
.vscode/
...@@ -35,10 +35,13 @@ ...@@ -35,10 +35,13 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#if defined OS_LYNX #if defined OS_LYNX
# include <sys/wait.h> # include <sys/wait.h>
#elif defined OS_POSIX #elif defined OS_POSIX
# include <sys/wait.h> # include <sys/wait.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h> # include <fcntl.h>
# include <unistd.h> # include <unistd.h>
#else #else
...@@ -65,23 +68,31 @@ ...@@ -65,23 +68,31 @@
#include "rt_errh_msg.h" #include "rt_errh_msg.h"
#include "rt_pwr_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 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 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 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 create_locks();
static void delete_locks(); static void delete_locks();
static void load_backup (); static void load_backup ();
static void logChanges (ini_sContext*); static void logChanges (ini_sContext *cp);
static void logCardinality (ini_sContext*); static void logCardinality (ini_sContext *cp);
static pwr_tStatus restart (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 pwr_tStatus start (ini_sContext *cp);
static void usage (char*); static void usage (char*);
static void ini_errl_cb( void *userdata, char *str, char severity, static void ini_errl_cb( void *userdata, char *str, char severity,
pwr_tStatus sts, int anix, int message_type); 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() void set_valid_time()
{ {
...@@ -98,14 +109,28 @@ int main (int argc, char **argv) ...@@ -98,14 +109,28 @@ int main (int argc, char **argv)
cp = createContext(argc, argv); cp = createContext(argc, argv);
ver_WriteVersionInfo("Proview Runtime Environment"); ver_WriteVersionInfo("ProviewR Runtime Environment");
if (cp->flags.b.restart) { if (cp->flags.b.restart) {
sts = interactive(argc, argv, cp); sts = interactive(argc, argv, cp);
} else if (cp->flags.b.stop) { } else if (cp->flags.b.stop) {
sts = stop(argc, argv, cp); sts = stop(cp);
} else { } else {
//Now lets daemonize if asked to
if (cp->flags.b.daemonize)
{
daemonize();
}
sts = start(cp); 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); sts = events(cp);
errh_LogInfo(&cp->log, "Ich sterbe!!"); errh_LogInfo(&cp->log, "Ich sterbe!!");
} }
...@@ -114,9 +139,7 @@ int main (int argc, char **argv) ...@@ -114,9 +139,7 @@ int main (int argc, char **argv)
} }
static pwr_tStatus static pwr_tStatus
start ( start (ini_sContext *cp)
ini_sContext *cp
)
{ {
pwr_tStatus sts; pwr_tStatus sts;
char console[80]; char console[80];
...@@ -332,11 +355,7 @@ interactive ( ...@@ -332,11 +355,7 @@ interactive (
} }
static pwr_tStatus static pwr_tStatus
stop ( stop (ini_sContext *cp)
int argc,
char **argv,
ini_sContext *cp
)
{ {
pwr_tStatus sts; pwr_tStatus sts;
qcom_sQid qid; qcom_sQid qid;
...@@ -351,7 +370,6 @@ stop ( ...@@ -351,7 +370,6 @@ stop (
// errh_Interactive(); // errh_Interactive();
if (!qcom_Init(&sts, 0, "pwr_ini_stop")) { if (!qcom_Init(&sts, 0, "pwr_ini_stop")) {
// errh_LogFatal(&cp->log, "qcom_Init, %m", sts);
exit(sts); exit(sts);
} }
...@@ -403,9 +421,7 @@ stop ( ...@@ -403,9 +421,7 @@ stop (
} }
static pwr_tStatus static pwr_tStatus
restart ( restart (ini_sContext *cp)
ini_sContext *cp
)
{ {
pwr_tStatus sts; pwr_tStatus sts;
char time[24]; char time[24];
...@@ -487,9 +503,7 @@ restart ( ...@@ -487,9 +503,7 @@ restart (
} }
static pwr_tStatus static pwr_tStatus
terminate ( terminate ()
ini_sContext *cp
)
{ {
pwr_tStatus sts; pwr_tStatus sts;
...@@ -531,12 +545,11 @@ terminate ( ...@@ -531,12 +545,11 @@ terminate (
errl_Unlink(); errl_Unlink();
#endif #endif
exit(1); exit(EXIT_SUCCESS);
} }
static int static int
ask_yes_no ( ask_yes_no (
ini_sContext *cp,
char *text char *text
) )
{ {
...@@ -548,9 +561,7 @@ ask_yes_no ( ...@@ -548,9 +561,7 @@ ask_yes_no (
} }
static int static int
checkErrors ( checkErrors (ini_sContext *cp)
ini_sContext *cp
)
{ {
if (cp->warnings == 0 && cp->errors == 0 && cp->fatals == 0) if (cp->warnings == 0 && cp->errors == 0 && cp->fatals == 0)
...@@ -562,7 +573,7 @@ checkErrors ( ...@@ -562,7 +573,7 @@ checkErrors (
errh_LogInfo(&cp->log, "Ignoring fatal errors, errors and warnings, continued..."); errh_LogInfo(&cp->log, "Ignoring fatal errors, errors and warnings, continued...");
return 1; return 1;
} else { } else {
return ask_yes_no(cp, "Do you want to continue"); return ask_yes_no("Do you want to continue");
} }
} }
if (cp->errors > 0) { if (cp->errors > 0) {
...@@ -571,7 +582,7 @@ checkErrors ( ...@@ -571,7 +582,7 @@ checkErrors (
errh_LogInfo(&cp->log, "Ignoring errors and warnings, continued..."); errh_LogInfo(&cp->log, "Ignoring errors and warnings, continued...");
return 1; return 1;
} else { } else {
return ask_yes_no(cp, "Do you want to continue"); return ask_yes_no("Do you want to continue");
} }
} }
if (cp->warnings > 0) { if (cp->warnings > 0) {
...@@ -580,7 +591,7 @@ checkErrors ( ...@@ -580,7 +591,7 @@ checkErrors (
errh_LogInfo(&cp->log, "Ignoring warnings, continued..."); errh_LogInfo(&cp->log, "Ignoring warnings, continued...");
return 1; return 1;
} else { } else {
return ask_yes_no(cp, "Do you want to continue"); return ask_yes_no("Do you want to continue");
} }
} }
return 1; return 1;
...@@ -727,6 +738,20 @@ createContext (int argc, char **argv) ...@@ -727,6 +738,20 @@ createContext (int argc, char **argv)
i++; i++;
i_incr = 1; i_incr = 1;
break; 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 '?': case '?':
usage(argv[0]); usage(argv[0]);
break; break;
...@@ -773,15 +798,15 @@ usage ( ...@@ -773,15 +798,15 @@ usage (
fprintf(stderr, " -v : verbose\n"); fprintf(stderr, " -v : verbose\n");
fprintf(stderr, " -w : ignore warnings\n"); fprintf(stderr, " -w : ignore warnings\n");
fprintf(stderr, " -A arg: use 'arg' as alias file\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, " -H arg: use 'arg' as hostname\n");
fprintf(stderr, " -N arg: use 'arg' as nodename\n"); fprintf(stderr, " -N arg: use 'arg' as nodename\n");
exit(1); exit(1);
} }
static void static void
logChanges ( logChanges (ini_sContext *cp)
ini_sContext *cp
)
{ {
lst_sEntry *vl; lst_sEntry *vl;
lst_sEntry *ol; lst_sEntry *ol;
...@@ -824,9 +849,7 @@ logChanges ( ...@@ -824,9 +849,7 @@ logChanges (
} }
static void static void
logCardinality ( logCardinality (ini_sContext *cp)
ini_sContext *cp
)
{ {
lst_sEntry *vl; lst_sEntry *vl;
ivol_sVolume *vp; ivol_sVolume *vp;
...@@ -838,9 +861,7 @@ logCardinality ( ...@@ -838,9 +861,7 @@ logCardinality (
} }
static pwr_tStatus static pwr_tStatus
events ( events (ini_sContext *cp)
ini_sContext *cp
)
{ {
lst_sEntry *pl; lst_sEntry *pl;
ini_sProc *pp; ini_sProc *pp;
...@@ -921,8 +942,8 @@ events ( ...@@ -921,8 +942,8 @@ events (
} }
} }
#endif #endif
} }
return INI__SUCCESS; return INI__SUCCESS;
} }
...@@ -1580,3 +1601,148 @@ static void ini_errl_cb( void *userdata, char *str, char severity, pwr_tStatus s ...@@ -1580,3 +1601,148 @@ static void ini_errl_cb( void *userdata, char *str, char severity, pwr_tStatus s
break; 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;
}
}
...@@ -57,7 +57,8 @@ typedef union { ...@@ -57,7 +57,8 @@ typedef union {
pwr_Bits( verbose , 1), pwr_Bits( verbose , 1),
pwr_Bits( restart , 1), pwr_Bits( restart , 1),
pwr_Bits( stop , 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( interactive , 1),
pwr_Bits( busid , 1), pwr_Bits( busid , 1),
...@@ -82,6 +83,7 @@ typedef union { ...@@ -82,6 +83,7 @@ typedef union {
#define ini_mContext_verbose pwr_Bit(3) #define ini_mContext_verbose pwr_Bit(3)
#define ini_mContext_restart pwr_Bit(4) #define ini_mContext_restart pwr_Bit(4)
#define ini_mContext_stop pwr_Bit(5) #define ini_mContext_stop pwr_Bit(5)
#define ini_mContext_daemonize pwr_Bit(6)
#define ini_mContext_interactive pwr_Bit(8) #define ini_mContext_interactive pwr_Bit(8)
#define ini_mContext_busid pwr_Bit(9) #define ini_mContext_busid pwr_Bit(9)
......
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