make use of lock file
Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
0bf3ef605d
commit
24cba92c7e
5 changed files with 83 additions and 7 deletions
|
@ -177,6 +177,29 @@ Incrementing numbers should appear in the browser display.
|
||||||
|
|
||||||
By default the test server logs to both stderr and syslog.
|
By default the test server logs to both stderr and syslog.
|
||||||
|
|
||||||
|
|
||||||
|
Running test server as a Daemon
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
You can use the -D option on the test server to have it fork into the
|
||||||
|
background and return immediately. In this daemonized mode all stderr is
|
||||||
|
disabled and logging goes only to syslog, eg, /var/log/messages or similar.
|
||||||
|
|
||||||
|
The server maintains a lockfile at /tmp/.lwsts-lock that contains the pid
|
||||||
|
of the master process, and deletes this file when the master process
|
||||||
|
terminates.
|
||||||
|
|
||||||
|
To stop the daemon, do
|
||||||
|
|
||||||
|
kill `cat /tmp/.lwsts-lock`
|
||||||
|
|
||||||
|
If it finds a stale lock (the pid mentioned in the file does not exist
|
||||||
|
any more) it will delete the lock and create a new one during startup.
|
||||||
|
|
||||||
|
If the lock is valid, the daemon will exit with a note on stderr that
|
||||||
|
it was already running.s
|
||||||
|
|
||||||
|
|
||||||
Using SSL on the server side
|
Using SSL on the server side
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
static int pid_daemon;
|
int pid_daemon;
|
||||||
static char lock_path[PATH_MAX];
|
static char lock_path[PATH_MAX];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -64,6 +64,14 @@ child_handler(int signum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lws_daemon_closing(int sigact)
|
||||||
|
{
|
||||||
|
if (getpid() == pid_daemon)
|
||||||
|
unlink(lock_path);
|
||||||
|
|
||||||
|
kill(getpid(), SIGKILL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* You just need to call this from your main(), when it
|
* You just need to call this from your main(), when it
|
||||||
* returns you are all set "in the background" decoupled
|
* returns you are all set "in the background" decoupled
|
||||||
|
@ -76,11 +84,31 @@ int
|
||||||
lws_daemonize(const char *_lock_path)
|
lws_daemonize(const char *_lock_path)
|
||||||
{
|
{
|
||||||
pid_t sid, parent;
|
pid_t sid, parent;
|
||||||
|
int fd;
|
||||||
|
char buf[10];
|
||||||
|
int n, ret;
|
||||||
|
struct sigaction act;
|
||||||
|
|
||||||
/* already a daemon */
|
/* already a daemon */
|
||||||
if (getppid() == 1)
|
if (getppid() == 1)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
|
fd = open(_lock_path, O_RDONLY);
|
||||||
|
if (fd > 0) {
|
||||||
|
n = read(fd, buf, sizeof buf);
|
||||||
|
close(fd);
|
||||||
|
if (n) {
|
||||||
|
n = atoi(buf);
|
||||||
|
ret = kill(n, 0);
|
||||||
|
if (ret >= 0) {
|
||||||
|
fprintf(stderr, "Daemon already running from pid %d, aborting\n", n);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Removing stale lock file %s from dead pid %d\n", _lock_path, n);
|
||||||
|
unlink(lock_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strncpy(lock_path, _lock_path, sizeof lock_path);
|
strncpy(lock_path, _lock_path, sizeof lock_path);
|
||||||
lock_path[sizeof(lock_path) - 1] = '\0';
|
lock_path[sizeof(lock_path) - 1] = '\0';
|
||||||
|
|
||||||
|
@ -114,6 +142,7 @@ lws_daemonize(const char *_lock_path)
|
||||||
|
|
||||||
/* At this point we are executing as the child process */
|
/* At this point we are executing as the child process */
|
||||||
parent = getppid();
|
parent = getppid();
|
||||||
|
pid_daemon = getpid();
|
||||||
|
|
||||||
/* Cancel certain signals */
|
/* Cancel certain signals */
|
||||||
signal(SIGCHLD, SIG_DFL); /* A child process dies */
|
signal(SIGCHLD, SIG_DFL); /* A child process dies */
|
||||||
|
@ -161,6 +190,13 @@ lws_daemonize(const char *_lock_path)
|
||||||
/* Tell the parent process that we are A-okay */
|
/* Tell the parent process that we are A-okay */
|
||||||
kill(parent, SIGUSR1);
|
kill(parent, SIGUSR1);
|
||||||
|
|
||||||
|
act.sa_handler = lws_daemon_closing;
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = 0;
|
||||||
|
act.sa_restorer = NULL;
|
||||||
|
|
||||||
|
sigaction(SIGTERM, &act, NULL);
|
||||||
|
|
||||||
/* return to continue what is now "the daemon" */
|
/* return to continue what is now "the daemon" */
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -703,6 +703,10 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
|
||||||
if (context->last_timeout_check_s != tv.tv_sec) {
|
if (context->last_timeout_check_s != tv.tv_sec) {
|
||||||
context->last_timeout_check_s = tv.tv_sec;
|
context->last_timeout_check_s = tv.tv_sec;
|
||||||
|
|
||||||
|
/* if our parent went down, don't linger around */
|
||||||
|
if (context->started_with_parent && kill(context->started_with_parent, 0) < 0)
|
||||||
|
kill(getpid(), SIGTERM);
|
||||||
|
|
||||||
/* global timeout check once per second */
|
/* global timeout check once per second */
|
||||||
|
|
||||||
for (n = 0; n < context->fds_count; n++) {
|
for (n = 0; n < context->fds_count; n++) {
|
||||||
|
@ -1443,12 +1447,17 @@ libwebsocket_create_context(int port, const char *interf,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
context = (struct libwebsocket_context *) malloc(sizeof(struct libwebsocket_context));
|
context = (struct libwebsocket_context *) malloc(sizeof(struct libwebsocket_context));
|
||||||
if (!context) {
|
if (!context) {
|
||||||
lwsl_err("No memory for websocket context\n");
|
lwsl_err("No memory for websocket context\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifndef NO_DAEMONIZE
|
||||||
|
extern int pid_daemon;
|
||||||
|
context->started_with_parent = pid_daemon;
|
||||||
|
lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
|
||||||
|
#endif
|
||||||
|
|
||||||
context->protocols = protocols;
|
context->protocols = protocols;
|
||||||
context->listen_port = port;
|
context->listen_port = port;
|
||||||
context->http_proxy_port = 0;
|
context->http_proxy_port = 0;
|
||||||
|
@ -1975,10 +1984,14 @@ libwebsockets_fork_service_loop(struct libwebsocket_context *context)
|
||||||
* solaris, could remember ppid right after fork and wait for it to change.
|
* solaris, could remember ppid right after fork and wait for it to change.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (getppid() == 1)
|
/* if our parent went down, don't linger around */
|
||||||
break;
|
if (context->started_with_parent && kill(context->started_with_parent, 0) < 0)
|
||||||
|
kill(getpid(), SIGTERM);
|
||||||
|
|
||||||
|
if (getppid() == 1)
|
||||||
|
break;
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -257,6 +257,8 @@ struct libwebsocket_context {
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
unsigned long last_timeout_check_s;
|
unsigned long last_timeout_check_s;
|
||||||
|
|
||||||
|
int started_with_parent;
|
||||||
|
|
||||||
int fd_random;
|
int fd_random;
|
||||||
int listen_service_modulo;
|
int listen_service_modulo;
|
||||||
int listen_service_count;
|
int listen_service_count;
|
||||||
|
|
|
@ -43,7 +43,6 @@ int count_pollfds;
|
||||||
|
|
||||||
#endif /* EXTERNAL_POLL */
|
#endif /* EXTERNAL_POLL */
|
||||||
|
|
||||||
//#define LWS_NO_FORK
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This demo server shows how to use libwebsockets for one or more
|
* This demo server shows how to use libwebsockets for one or more
|
||||||
|
@ -562,6 +561,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_DAEMONIZE
|
||||||
/*
|
/*
|
||||||
* normally lock path would be /var/lock/lwsts or similar, to
|
* normally lock path would be /var/lock/lwsts or similar, to
|
||||||
* simplify getting started without having to take care about
|
* simplify getting started without having to take care about
|
||||||
|
@ -571,7 +571,7 @@ int main(int argc, char **argv)
|
||||||
fprintf(stderr, "Failed to daemonize\n");
|
fprintf(stderr, "Failed to daemonize\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* we will only try to log things according to our debug_level */
|
/* we will only try to log things according to our debug_level */
|
||||||
setlogmask(LOG_UPTO (LOG_DEBUG));
|
setlogmask(LOG_UPTO (LOG_DEBUG));
|
||||||
openlog("lwsts", syslog_options, LOG_DAEMON);
|
openlog("lwsts", syslog_options, LOG_DAEMON);
|
||||||
|
@ -685,6 +685,8 @@ int main(int argc, char **argv)
|
||||||
lwsl_err("Unable to fork service loop %d\n", n);
|
lwsl_err("Unable to fork service loop %d\n", n);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (n)
|
||||||
|
exit(0);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue