mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-11-04 08:52:47 +00:00 
			
		
		
		
	Afterward, git grep ZoL matches: * README.md: * [ZoL Site](https://zfsonlinux.org) - Correct * etc/default/zfs.in:# ZoL userland configuration. - Changing this would induce a needless upgrade-check, if the user has modified the configuration; this can be updated the next time the defaults change * module/zfs/dmu_send.c: * ZoL < 0.7 does not handle [...] - Before 0.7 is ZoL, so fair enough Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Issue #11956
		
			
				
	
	
		
			257 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * This file is part of the ZFS Event Daemon (ZED).
 | 
						|
 *
 | 
						|
 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
 | 
						|
 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
 | 
						|
 * Refer to the OpenZFS 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);
 | 
						|
}
 |