X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2Fpvefw-logger.c;h=f4321fbb4f53a489e19f706ce7960dad257dd118;hp=3a069f1e1c4c4f7e868a3a2fe7cba64cfb031860;hb=3bce273b66ebea7898c4cfe0af38c4278054c57c;hpb=5b06fd6c0e9ce50c58cfb32f6820d1ebce5858c4;ds=inline diff --git a/src/pvefw-logger.c b/src/pvefw-logger.c index 3a069f1..f4321fb 100644 --- a/src/pvefw-logger.c +++ b/src/pvefw-logger.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -47,12 +48,14 @@ #include #include -#include static struct nflog_handle *logh = NULL; static struct nlif_handle *nlifh = NULL; GMainLoop *main_loop; +gboolean foreground = FALSE; +gboolean debug = FALSE; + /* LOG FORMAT: @@ -128,6 +131,8 @@ log_writer_thread(gpointer data) continue; } + if (debug) fputs(le->buf, stdout); + int res = safe_write(outfd, le->buf, le->len); g_free(le); @@ -622,38 +627,74 @@ nlif_read_cb(GIOChannel *source, } static gboolean -terminate_request(gpointer data) +signal_read_cb(GIOChannel *source, + GIOCondition condition, + gpointer data) { - terminate_threads = TRUE; + int rv = 0; + struct signalfd_siginfo si; - log_status_message(5, "received terminate request (signal)"); + int fd = g_io_channel_unix_get_fd(source); - g_main_loop_quit(main_loop); + if ((rv = read(fd, &si, sizeof(si))) && rv >= 0) { + terminate_threads = TRUE; + log_status_message(5, "received terminate request (signal)"); + g_main_loop_quit(main_loop); + } return TRUE; } - int main(int argc, char *argv[]) { int lockfd = -1; - gboolean foreground = FALSE; + int sigfd = -1; + gboolean wrote_pidfile = FALSE; g_thread_init(NULL); openlog("pvepw-logger", LOG_CONS|LOG_PID, LOG_DAEMON); + GOptionContext *context; + + GOptionEntry entries[] = { + { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Turn on debug messages", NULL }, + { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, "Do not daemonize server", NULL }, + { NULL }, + }; + + context = g_option_context_new(""); + g_option_context_add_main_entries (context, entries, NULL); + + GError *err = NULL; + if (!g_option_context_parse (context, &argc, &argv, &err)) { + fprintf(stderr, "error: %s\n", err->message); + fprintf(stderr, "%s", g_option_context_get_help(context, FALSE, NULL)); + g_error_free (err); + exit(-1); + } + + if (optind < argc) { + fprintf(stderr, "error: too many arguments\n"); + fprintf(stderr, "%s", g_option_context_get_help(context, FALSE, NULL)); + exit(-1); + } + + g_option_context_free(context); + + if (debug) foreground = TRUE; + if ((lockfd = open(LOCKFILE, O_RDWR|O_CREAT|O_APPEND, 0644)) == -1) { - fprintf(stderr, "unable to create lock '%s': %s", LOCKFILE, strerror (errno) ); + fprintf(stderr, "unable to create lock '%s': %s\n", LOCKFILE, strerror (errno) ); exit(-1); } for (int i = 10; i >= 0; i--) { if (flock(lockfd, LOCK_EX|LOCK_NB) != 0) { if (!i) { - fprintf(stderr, "unable to aquire lock '%s': %s", LOCKFILE, strerror (errno)); + fprintf(stderr, "unable to aquire lock '%s': %s\n", LOCKFILE, strerror (errno)); exit(-1); } if (i == 10) @@ -664,7 +705,7 @@ main(int argc, char *argv[]) } if ((outfd = open(LOGFILE, O_WRONLY|O_CREAT|O_APPEND, 0644)) == -1) { - fprintf(stderr, "unable to open file '%s': %s", LOGFILE, strerror (errno)); + fprintf(stderr, "unable to open file '%s': %s\n", LOGFILE, strerror (errno)); exit(-1); } @@ -692,7 +733,7 @@ main(int argc, char *argv[]) struct nflog_g_handle *qh = nflog_bind_group(logh, 0); if (!qh) { - fprintf(stderr, "no handle for group 1\n"); + fprintf(stderr, "no nflog handle for group 0\n"); exit(-1); } @@ -706,6 +747,18 @@ main(int argc, char *argv[]) exit(-1); } + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + + sigprocmask(SIG_BLOCK, &mask, NULL); + + if ((sigfd = signalfd(-1, &mask, SFD_NONBLOCK)) < 0) { + fprintf(stderr, "unable to open signalfd: %s\n", strerror (errno)); + exit(-1); + } + if (!foreground) { pid_t cpid = fork(); @@ -753,13 +806,15 @@ main(int argc, char *argv[]) g_io_add_watch(nflog_ch, G_IO_IN, nflog_read_cb, NULL); + GIOChannel *sig_ch = g_io_channel_unix_new(sigfd); + if (!g_io_add_watch(sig_ch, G_IO_IN, signal_read_cb, NULL)) { + exit(-1); + } + GThread *wthread = g_thread_new("log_writer_thread", log_writer_thread, NULL); main_loop = g_main_loop_new(NULL, TRUE); - g_unix_signal_add(SIGINT, terminate_request, NULL); - g_unix_signal_add(SIGTERM, terminate_request, NULL); - g_main_loop_run(main_loop); log_status_message(5, "stopping pvefw logger");