Capture and log STDOUT and STDERR output from dhcp-script.

This commit is contained in:
Petr Menšík
2017-04-16 20:20:08 +01:00
committed by Simon Kelley
parent bc515b71ec
commit c77fb9d8f0
6 changed files with 100 additions and 33 deletions

View File

@@ -1302,6 +1302,7 @@ static void async_event(int pipe, time_t now)
daemon->tcp_pids[i] = 0;
break;
#if defined(HAVE_SCRIPT)
case EVENT_KILLED:
my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
break;
@@ -1315,12 +1316,19 @@ static void async_event(int pipe, time_t now)
daemon->lease_change_command, strerror(ev.data));
break;
case EVENT_SCRIPT_LOG:
my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
free(msg);
msg = NULL;
break;
/* necessary for fatal errors in helper */
case EVENT_USER_ERR:
case EVENT_DIE:
case EVENT_LUA_ERR:
fatal_event(&ev, msg);
break;
#endif
case EVENT_REOPEN:
/* Note: this may leave TCP-handling processes with the old file still open.

View File

@@ -145,30 +145,31 @@ struct event_desc {
int event, data, msg_sz;
};
#define EVENT_RELOAD 1
#define EVENT_DUMP 2
#define EVENT_ALARM 3
#define EVENT_TERM 4
#define EVENT_CHILD 5
#define EVENT_REOPEN 6
#define EVENT_EXITED 7
#define EVENT_KILLED 8
#define EVENT_EXEC_ERR 9
#define EVENT_PIPE_ERR 10
#define EVENT_USER_ERR 11
#define EVENT_CAP_ERR 12
#define EVENT_PIDFILE 13
#define EVENT_HUSER_ERR 14
#define EVENT_GROUP_ERR 15
#define EVENT_DIE 16
#define EVENT_LOG_ERR 17
#define EVENT_FORK_ERR 18
#define EVENT_LUA_ERR 19
#define EVENT_TFTP_ERR 20
#define EVENT_INIT 21
#define EVENT_NEWADDR 22
#define EVENT_NEWROUTE 23
#define EVENT_TIME_ERR 24
#define EVENT_RELOAD 1
#define EVENT_DUMP 2
#define EVENT_ALARM 3
#define EVENT_TERM 4
#define EVENT_CHILD 5
#define EVENT_REOPEN 6
#define EVENT_EXITED 7
#define EVENT_KILLED 8
#define EVENT_EXEC_ERR 9
#define EVENT_PIPE_ERR 10
#define EVENT_USER_ERR 11
#define EVENT_CAP_ERR 12
#define EVENT_PIDFILE 13
#define EVENT_HUSER_ERR 14
#define EVENT_GROUP_ERR 15
#define EVENT_DIE 16
#define EVENT_LOG_ERR 17
#define EVENT_FORK_ERR 18
#define EVENT_LUA_ERR 19
#define EVENT_TFTP_ERR 20
#define EVENT_INIT 21
#define EVENT_NEWADDR 22
#define EVENT_NEWROUTE 23
#define EVENT_TIME_ERR 24
#define EVENT_SCRIPT_LOG 25
/* Exit codes. */
#define EC_GOOD 0
@@ -243,8 +244,9 @@ struct event_desc {
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
#define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON
#define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON
#define MS_SCRIPT LOG_MAIL
struct all_addr {
union {

View File

@@ -14,6 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "dnsmasq.h"
#ifdef HAVE_SCRIPT
@@ -135,7 +136,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
max_fd != STDIN_FILENO && max_fd != pipefd[0] &&
max_fd != event_fd && max_fd != err_fd)
close(max_fd);
#ifdef HAVE_LUASCRIPT
if (daemon->luascript)
{
@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
unsigned char *buf = (unsigned char *)daemon->namebuff;
unsigned char *end, *extradata, *alloc_buff = NULL;
int is6, err = 0;
int pipeout[2];
free(alloc_buff);
@@ -472,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if (!daemon->lease_change_command)
continue;
/* Pipe to capture stdout and stderr from script */
if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1)
continue;
/* possible fork errors are all temporary resource problems */
while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
sleep(2);
if (pid == -1)
continue;
{
if (!option_bool(OPT_DEBUG))
{
close(pipeout[0]);
close(pipeout[1]);
}
continue;
}
/* wait for child to complete */
if (pid != 0)
{
if (!option_bool(OPT_DEBUG))
{
FILE *fp;
close(pipeout[1]);
/* Read lines sent to stdout/err by the script and pass them back to be logged */
if (!(fp = fdopen(pipeout[0], "r")))
close(pipeout[0]);
else
{
while (fgets(daemon->packet, daemon->packet_buff_sz, fp))
{
/* do not include new lines, log will append them */
size_t len = strlen(daemon->packet);
if (len > 0)
{
--len;
if (daemon->packet[len] == '\n')
daemon->packet[len] = 0;
}
send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet);
}
fclose(fp);
}
}
/* reap our children's children, if necessary */
while (1)
{
@@ -504,6 +544,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue;
}
if (!option_bool(OPT_DEBUG))
{
/* map stdout/stderr of script to pipeout */
close(pipeout[0]);
dup2(pipeout[1], STDOUT_FILENO);
dup2(pipeout[1], STDERR_FILENO);
close(pipeout[1]);
}
if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
{
@@ -580,7 +629,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
hostname = NULL;
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
}
}
/* we need to have the event_fd around if exec fails */
if ((i = fcntl(event_fd, F_GETFD)) != -1)
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);

View File

@@ -288,7 +288,9 @@ void my_syslog(int priority, const char *format, ...)
func = "-tftp";
else if ((LOG_FACMASK & priority) == MS_DHCP)
func = "-dhcp";
else if ((LOG_FACMASK & priority) == MS_SCRIPT)
func = "-script";
#ifdef LOG_PRI
priority = LOG_PRI(priority);
#else