The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/cmd/zed/zed_log.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * This file is part of the ZFS Event Daemon (ZED).
    3  *
    4  * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
    5  * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
    6  * Refer to the OpenZFS git commit log for authoritative copyright attribution.
    7  *
    8  * The contents of this file are subject to the terms of the
    9  * Common Development and Distribution License Version 1.0 (CDDL-1.0).
   10  * You can obtain a copy of the license from the top-level file
   11  * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
   12  * You may not use this file except in compliance with the license.
   13  */
   14 
   15 #include <assert.h>
   16 #include <errno.h>
   17 #include <stdarg.h>
   18 #include <stdio.h>
   19 #include <stdlib.h>
   20 #include <string.h>
   21 #include <sys/types.h>
   22 #include <syslog.h>
   23 #include <unistd.h>
   24 #include "zed_log.h"
   25 
   26 #define ZED_LOG_MAX_LOG_LEN     1024
   27 
   28 static struct {
   29         unsigned do_stderr:1;
   30         unsigned do_syslog:1;
   31         const char *identity;
   32         int priority;
   33         int pipe_fd[2];
   34 } _ctx;
   35 
   36 /*
   37  * Initialize the logging subsystem.
   38  */
   39 void
   40 zed_log_init(const char *identity)
   41 {
   42         if (identity) {
   43                 const char *p = strrchr(identity, '/');
   44                 _ctx.identity = (p != NULL) ? p + 1 : identity;
   45         } else {
   46                 _ctx.identity = NULL;
   47         }
   48         _ctx.pipe_fd[0] = -1;
   49         _ctx.pipe_fd[1] = -1;
   50 }
   51 
   52 /*
   53  * Shutdown the logging subsystem.
   54  */
   55 void
   56 zed_log_fini(void)
   57 {
   58         zed_log_stderr_close();
   59         zed_log_syslog_close();
   60 }
   61 
   62 /*
   63  * Create pipe for communicating daemonization status between the parent and
   64  * child processes across the double-fork().
   65  */
   66 void
   67 zed_log_pipe_open(void)
   68 {
   69         if ((_ctx.pipe_fd[0] != -1) || (_ctx.pipe_fd[1] != -1))
   70                 zed_log_die("Invalid use of zed_log_pipe_open in PID %d",
   71                     (int)getpid());
   72 
   73         if (pipe(_ctx.pipe_fd) < 0)
   74                 zed_log_die("Failed to create daemonize pipe in PID %d: %s",
   75                     (int)getpid(), strerror(errno));
   76 }
   77 
   78 /*
   79  * Close the read-half of the daemonize pipe.
   80  *
   81  * This should be called by the child after fork()ing from the parent since
   82  * the child will never read from this pipe.
   83  */
   84 void
   85 zed_log_pipe_close_reads(void)
   86 {
   87         if (_ctx.pipe_fd[0] < 0)
   88                 zed_log_die(
   89                     "Invalid use of zed_log_pipe_close_reads in PID %d",
   90                     (int)getpid());
   91 
   92         if (close(_ctx.pipe_fd[0]) < 0)
   93                 zed_log_die(
   94                     "Failed to close reads on daemonize pipe in PID %d: %s",
   95                     (int)getpid(), strerror(errno));
   96 
   97         _ctx.pipe_fd[0] = -1;
   98 }
   99 
  100 /*
  101  * Close the write-half of the daemonize pipe.
  102  *
  103  * This should be called by the parent after fork()ing its child since the
  104  * parent will never write to this pipe.
  105  *
  106  * This should also be called by the child once initialization is complete
  107  * in order to signal the parent that it can safely exit.
  108  */
  109 void
  110 zed_log_pipe_close_writes(void)
  111 {
  112         if (_ctx.pipe_fd[1] < 0)
  113                 zed_log_die(
  114                     "Invalid use of zed_log_pipe_close_writes in PID %d",
  115                     (int)getpid());
  116 
  117         if (close(_ctx.pipe_fd[1]) < 0)
  118                 zed_log_die(
  119                     "Failed to close writes on daemonize pipe in PID %d: %s",
  120                     (int)getpid(), strerror(errno));
  121 
  122         _ctx.pipe_fd[1] = -1;
  123 }
  124 
  125 /*
  126  * Block on reading from the daemonize pipe until signaled by the child
  127  * (via zed_log_pipe_close_writes()) that initialization is complete.
  128  *
  129  * This should only be called by the parent while waiting to exit after
  130  * fork()ing the child.
  131  */
  132 void
  133 zed_log_pipe_wait(void)
  134 {
  135         ssize_t n;
  136         char c;
  137 
  138         if (_ctx.pipe_fd[0] < 0)
  139                 zed_log_die("Invalid use of zed_log_pipe_wait in PID %d",
  140                     (int)getpid());
  141 
  142         for (;;) {
  143                 n = read(_ctx.pipe_fd[0], &c, sizeof (c));
  144                 if (n < 0) {
  145                         if (errno == EINTR)
  146                                 continue;
  147                         zed_log_die(
  148                             "Failed to read from daemonize pipe in PID %d: %s",
  149                             (int)getpid(), strerror(errno));
  150                 }
  151                 if (n == 0) {
  152                         break;
  153                 }
  154         }
  155 }
  156 
  157 /*
  158  * Start logging messages at the syslog [priority] level or higher to stderr.
  159  * Refer to syslog(3) for valid priority values.
  160  */
  161 void
  162 zed_log_stderr_open(int priority)
  163 {
  164         _ctx.do_stderr = 1;
  165         _ctx.priority = priority;
  166 }
  167 
  168 /*
  169  * Stop logging messages to stderr.
  170  */
  171 void
  172 zed_log_stderr_close(void)
  173 {
  174         if (_ctx.do_stderr)
  175                 _ctx.do_stderr = 0;
  176 }
  177 
  178 /*
  179  * Start logging messages to syslog.
  180  * Refer to syslog(3) for valid option/facility values.
  181  */
  182 void
  183 zed_log_syslog_open(int facility)
  184 {
  185         _ctx.do_syslog = 1;
  186         openlog(_ctx.identity, LOG_NDELAY | LOG_PID, facility);
  187 }
  188 
  189 /*
  190  * Stop logging messages to syslog.
  191  */
  192 void
  193 zed_log_syslog_close(void)
  194 {
  195         if (_ctx.do_syslog) {
  196                 _ctx.do_syslog = 0;
  197                 closelog();
  198         }
  199 }
  200 
  201 /*
  202  * Auxiliary function to log a message to syslog and/or stderr.
  203  */
  204 static void
  205 _zed_log_aux(int priority, const char *fmt, va_list vargs)
  206 {
  207         char buf[ZED_LOG_MAX_LOG_LEN];
  208         int n;
  209 
  210         if (!fmt)
  211                 return;
  212 
  213         n = vsnprintf(buf, sizeof (buf), fmt, vargs);
  214         if ((n < 0) || (n >= sizeof (buf))) {
  215                 buf[sizeof (buf) - 2] = '+';
  216                 buf[sizeof (buf) - 1] = '\0';
  217         }
  218 
  219         if (_ctx.do_syslog)
  220                 syslog(priority, "%s", buf);
  221 
  222         if (_ctx.do_stderr && (priority <= _ctx.priority))
  223                 fprintf(stderr, "%s\n", buf);
  224 }
  225 
  226 /*
  227  * Log a message at the given [priority] level specified by the printf-style
  228  * format string [fmt].
  229  */
  230 void
  231 zed_log_msg(int priority, const char *fmt, ...)
  232 {
  233         va_list vargs;
  234 
  235         if (fmt) {
  236                 va_start(vargs, fmt);
  237                 _zed_log_aux(priority, fmt, vargs);
  238                 va_end(vargs);
  239         }
  240 }
  241 
  242 /*
  243  * Log a fatal error message specified by the printf-style format string [fmt].
  244  */
  245 void
  246 zed_log_die(const char *fmt, ...)
  247 {
  248         va_list vargs;
  249 
  250         if (fmt) {
  251                 va_start(vargs, fmt);
  252                 _zed_log_aux(LOG_ERR, fmt, vargs);
  253                 va_end(vargs);
  254         }
  255         exit(EXIT_FAILURE);
  256 }

Cache object: 01be099d95b78a34a6ac56f9a39f687b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.