view src/logerr.h @ 5525:26b5d9bc2985 draft

privsep: Send all log messages to the privileged actioneer If dhcpcd starts and no syslogd implementation is running then various syscall filters could be triggered when dhcpcd wants to syslog and it's already in a chroot. Not all libc openlog implementations support LOG_NDELAY and openlog does not return an error code and can also mask errno back to 0. So we have no way of knowing if we have a syslog connection or not. This means we cannot cache the connection at startup because syslog itself will try and open if no connection. As such, all logging is now directed to the dhcpcd privileged actioneer process which will handle all the syslog and log file writing actions. The only downside of this approach (other than an extra fd per process) is that we no longer know which PID raised the message. While we could put the correct PID in the logfile as we control the API, we cannot put it into syslog as we cannot control that API. As all privsep errors should log which function they came from this will hopefully not be an issue as on the happy path only the master process will log stuff.
author Roy Marples <roy@marples.name>
date Fri, 30 Oct 2020 03:43:51 +0000
parents ff7c7b4799b3
children b1a3d9055662
line wrap: on
line source

/* SPDX-License-Identifier: BSD-2-Clause */
/*
 * logerr: errx with logging
 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
 * All rights reserved

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef LOGERR_H
#define LOGERR_H

#include <sys/param.h>

#ifndef __printflike
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
#define	__printflike(a, b) __attribute__((format(printf, a, b)))
#else
#define	__printflike(a, b)
#endif
#endif /* !__printflike */

/* Please do not call log_* functions directly, use macros below */
__printflike(1, 2) void log_debug(const char *, ...);
__printflike(1, 2) void log_debugx(const char *, ...);
__printflike(1, 2) void log_info(const char *, ...);
__printflike(1, 2) void log_infox(const char *, ...);
__printflike(1, 2) void log_warn(const char *, ...);
__printflike(1, 2) void log_warnx(const char *, ...);
__printflike(1, 2) void log_err(const char *, ...);
__printflike(1, 2) void log_errx(const char *, ...);
#define	LOGERROR	logerr("%s: %d", __FILE__, __LINE__)

__printflike(2, 3) void logmessage(int pri, const char *fmt, ...);
__printflike(2, 3) void logerrmessage(int pri, const char *fmt, ...);

/*
 * These are macros to prevent taking address of them so
 * __FILE__, __LINE__, etc can easily be added.
 *
 * We should be using
 * #define loginfox(fmt, __VA_OPT__(,) __VA_ARGS__)
 * but that requires gcc-8 or clang-6 and we still have a need to support
 * old OS's without modern compilers.
 *
 * Likewise, ##__VA_ARGS__ can't be used as that's a gcc only extension.
 *
 * The solution is to put fmt into __VA_ARGS__.
 * It's not pretty but it's 100% portable.
 */
#define logdebug(...)	log_debug(__VA_ARGS__)
#define logdebugx(...)	log_debugx(__VA_ARGS__)
#define loginfo(...)	log_info(__VA_ARGS__)
#define loginfox(...)	log_infox(__VA_ARGS__)
#define logwarn(...)	log_warn(__VA_ARGS__)
#define logwarnx(...)	log_warnx(__VA_ARGS__)
#define logerr(...)	log_err(__VA_ARGS__)
#define logerrx(...)	log_errx(__VA_ARGS__)

/* For syslog in a chroot */
int loggetsyslogfd(void);
void logsetsyslogfd(int);
int loghandlesyslogfd(int);

unsigned int loggetopts(void);
void logsetopts(unsigned int);
#define	LOGERR_DEBUG	(1U << 6)
#define	LOGERR_QUIET	(1U << 7)
#define	LOGERR_LOG	(1U << 11)
#define	LOGERR_LOG_DATE	(1U << 12)
#define	LOGERR_LOG_HOST	(1U << 13)
#define	LOGERR_LOG_TAG	(1U << 14)
#define	LOGERR_LOG_PID	(1U << 15)
#define	LOGERR_ERR	(1U << 21)
#define	LOGERR_ERR_DATE	(1U << 22)
#define	LOGERR_ERR_HOST	(1U << 23)
#define	LOGERR_ERR_TAG	(1U << 24)
#define	LOGERR_ERR_PID	(1U << 25)

/* To build tag support or not. */
//#define	LOGERR_TAG
#if defined(LOGERR_TAG)
void logsettag(const char *);
#endif

int logopen(const char *);
void logclose(void);
int logreopen(void);

#endif