/*
 * This file is part of the ZFS Event Daemon (ZED)
 * for ZFS on Linux (ZoL) <http://zfsonlinux.org/>.
 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
 * Refer to the ZoL git commit log for authoritative copyright attribution.
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License Version 1.0 (CDDL-1.0).
 * You can obtain a copy of the license from the top-level file
 * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
 * You may not use this file except in compliance with the license.
 */

#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#include "zed_log.h"

#define	ZED_LOG_MAX_LOG_LEN	1024

static struct {
	unsigned do_stderr:1;
	unsigned do_syslog:1;
	const char *identity;
	int priority;
	int pipe_fd[2];
} _ctx;

/*
 * Initialize the logging subsystem.
 */
void
zed_log_init(const char *identity)
{
	if (identity) {
		const char *p = strrchr(identity, '/');
		_ctx.identity = (p != NULL) ? p + 1 : identity;
	} else {
		_ctx.identity = NULL;
	}
	_ctx.pipe_fd[0] = -1;
	_ctx.pipe_fd[1] = -1;
}

/*
 * Shutdown the logging subsystem.
 */
void
zed_log_fini(void)
{
	zed_log_stderr_close();
	zed_log_syslog_close();
}

/*
 * Create pipe for communicating daemonization status between the parent and
 * child processes across the double-fork().
 */
void
zed_log_pipe_open(void)
{
	if ((_ctx.pipe_fd[0] != -1) || (_ctx.pipe_fd[1] != -1))
		zed_log_die("Invalid use of zed_log_pipe_open in PID %d",
		    (int)getpid());

	if (pipe(_ctx.pipe_fd) < 0)
		zed_log_die("Failed to create daemonize pipe in PID %d: %s",
		    (int)getpid(), strerror(errno));
}

/*
 * Close the read-half of the daemonize pipe.
 *
 * This should be called by the child after fork()ing from the parent since
 * the child will never read from this pipe.
 */
void
zed_log_pipe_close_reads(void)
{
	if (_ctx.pipe_fd[0] < 0)
		zed_log_die(
		    "Invalid use of zed_log_pipe_close_reads in PID %d",
		    (int)getpid());

	if (close(_ctx.pipe_fd[0]) < 0)
		zed_log_die(
		    "Failed to close reads on daemonize pipe in PID %d: %s",
		    (int)getpid(), strerror(errno));

	_ctx.pipe_fd[0] = -1;
}

/*
 * Close the write-half of the daemonize pipe.
 *
 * This should be called by the parent after fork()ing its child since the
 * parent will never write to this pipe.
 *
 * This should also be called by the child once initialization is complete
 * in order to signal the parent that it can safely exit.
 */
void
zed_log_pipe_close_writes(void)
{
	if (_ctx.pipe_fd[1] < 0)
		zed_log_die(
		    "Invalid use of zed_log_pipe_close_writes in PID %d",
		    (int)getpid());

	if (close(_ctx.pipe_fd[1]) < 0)
		zed_log_die(
		    "Failed to close writes on daemonize pipe in PID %d: %s",
		    (int)getpid(), strerror(errno));

	_ctx.pipe_fd[1] = -1;
}

/*
 * Block on reading from the daemonize pipe until signaled by the child
 * (via zed_log_pipe_close_writes()) that initialization is complete.
 *
 * This should only be called by the parent while waiting to exit after
 * fork()ing the child.
 */
void
zed_log_pipe_wait(void)
{
	ssize_t n;
	char c;

	if (_ctx.pipe_fd[0] < 0)
		zed_log_die("Invalid use of zed_log_pipe_wait in PID %d",
		    (int)getpid());

	for (;;) {
		n = read(_ctx.pipe_fd[0], &c, sizeof (c));
		if (n < 0) {
			if (errno == EINTR)
				continue;
			zed_log_die(
			    "Failed to read from daemonize pipe in PID %d: %s",
			    (int)getpid(), strerror(errno));
		}
		if (n == 0) {
			break;
		}
	}
}

/*
 * Start logging messages at the syslog [priority] level or higher to stderr.
 * Refer to syslog(3) for valid priority values.
 */
void
zed_log_stderr_open(int priority)
{
	_ctx.do_stderr = 1;
	_ctx.priority = priority;
}

/*
 * Stop logging messages to stderr.
 */
void
zed_log_stderr_close(void)
{
	if (_ctx.do_stderr)
		_ctx.do_stderr = 0;
}

/*
 * Start logging messages to syslog.
 * Refer to syslog(3) for valid option/facility values.
 */
void
zed_log_syslog_open(int facility)
{
	_ctx.do_syslog = 1;
	openlog(_ctx.identity, LOG_NDELAY | LOG_PID, facility);
}

/*
 * Stop logging messages to syslog.
 */
void
zed_log_syslog_close(void)
{
	if (_ctx.do_syslog) {
		_ctx.do_syslog = 0;
		closelog();
	}
}

/*
 * Auxiliary function to log a message to syslog and/or stderr.
 */
static void
_zed_log_aux(int priority, const char *fmt, va_list vargs)
{
	char buf[ZED_LOG_MAX_LOG_LEN];
	int n;

	if (!fmt)
		return;

	n = vsnprintf(buf, sizeof (buf), fmt, vargs);
	if ((n < 0) || (n >= sizeof (buf))) {
		buf[sizeof (buf) - 2] = '+';
		buf[sizeof (buf) - 1] = '\0';
	}

	if (_ctx.do_syslog)
		syslog(priority, "%s", buf);

	if (_ctx.do_stderr && (priority <= _ctx.priority))
		fprintf(stderr, "%s\n", buf);
}

/*
 * Log a message at the given [priority] level specified by the printf-style
 * format string [fmt].
 */
void
zed_log_msg(int priority, const char *fmt, ...)
{
	va_list vargs;

	if (fmt) {
		va_start(vargs, fmt);
		_zed_log_aux(priority, fmt, vargs);
		va_end(vargs);
	}
}

/*
 * Log a fatal error message specified by the printf-style format string [fmt].
 */
void
zed_log_die(const char *fmt, ...)
{
	va_list vargs;

	if (fmt) {
		va_start(vargs, fmt);
		_zed_log_aux(LOG_ERR, fmt, vargs);
		va_end(vargs);
	}
	exit(EXIT_FAILURE);
}
