2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use is subject to license terms.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 2007, The Storage Networking Industry Association. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl/*
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <errno.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <limits.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdarg.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdlib.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <syslog.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <time.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <string.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/stat.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar#include <libgen.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <pthread.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <errno.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd_log.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd_common.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl#define LOG_PATH "/var/log/ndmp"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define LOG_FNAME "ndmplog.%d"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define LOG_FILE_CNT 5
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define LOG_FILE_SIZE 4 * 1024 * 1024
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define LOG_SIZE_INT 256
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Krylstatic boolean_t debug = B_FALSE;
faac71c002f7c7a98741f991b25937b24f309df0Jan Krylstatic boolean_t log_to_stderr = B_FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic FILE *logfp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int ndmp_synclog = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Since we use buffered file I/O for log file, the thread may lose CPU.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * At this time, another thread can destroy the contents of the buffer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * that must be written to the log file. The following mutex is used
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to allow only one thread to write into the log file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
faac71c002f7c7a98741f991b25937b24f309df0Jan Krylstatic mutex_t log_lock;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *priority_str[] = {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "EMERGENCY",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "ALERT",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "CRITICAL",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "ERROR",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "WARNING",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "NOTICE",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "INFO",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "DEBUG",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar};
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * mk_pathname
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Append the NDMP working directory path to the specified file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdarmk_pathname(char *fname, char *path, int idx)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar static char buf[PATH_MAX];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar static char name[NAME_MAX];
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar char *fmt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl len = strnlen(path, PATH_MAX);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fmt = (path[len - 1] == '/') ? "%s%s" : "%s/%s";
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED variable format specifier */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(name, NAME_MAX, fname, idx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED variable format specifier */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(buf, PATH_MAX, fmt, path, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * openlogfile
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Open the NDMP log file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaropenlogfile(char *fname, char *mode)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl assert(fname != NULL && *fname != '\0' &&
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl mode != NULL && *mode != '\0');
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if ((logfp = fopen(fname, mode)) == NULL) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl perror("Error opening logfile");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) mutex_init(&log_lock, 0, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * log_write_cur_time
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Add the current time for each log entry
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarlog_write_cur_time(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct tm tm;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar time_t secs;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar secs = time(NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) localtime_r(&secs, &tm);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fprintf(logfp, "%2d/%02d %2d:%02d:%02d ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tm.tm_mon + 1, tm.tm_mday,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tm.tm_hour, tm.tm_min, tm.tm_sec);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * add_newline
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The new line at the end of each log
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaradd_newline(char *fmt)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fmt[strlen(fmt) - 1] != '\n')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fputc('\n', logfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * log_append
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Append the message to the end of the log
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarlog_append(char *msg)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar log_write_cur_time();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fwrite(msg, 1, strlen(msg), logfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar add_newline(msg);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_synclog)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fflush(logfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_log_openfile
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl * Open the log file either for append or write mode. This function should
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl * be called while ndmpd is still running single-threaded and in foreground.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
faac71c002f7c7a98741f991b25937b24f309df0Jan Krylndmp_log_open_file(boolean_t to_stderr, boolean_t override_debug)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl char *fname, *mode, *lpath;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char oldfname[PATH_MAX];
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar struct stat64 st;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl log_to_stderr = to_stderr;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl /* read debug property if it isn't overriden by cmd line option */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (override_debug)
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl debug = B_TRUE;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl else
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl debug = ndmpd_get_prop_yorn(NDMP_DEBUG_MODE) ? B_TRUE : B_FALSE;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl /* Create the debug path if it doesn't exist */
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar lpath = ndmpd_get_prop(NDMP_DEBUG_PATH);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar if ((lpath == NULL) || (*lpath == NULL))
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl lpath = LOG_PATH;
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar if (stat64(lpath, &st) < 0) {
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar if (mkdirp(lpath, 0755) < 0) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr,
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl "Could not create log path %s: %s\n",
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl lpath, strerror(errno));
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar lpath = "/var";
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar }
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar }
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NDMP log file name will be {logfilename}.0 to {logfilename}.5, where
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * {logfilename}.0 will always be the latest and the {logfilename}.5
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will be the oldest available file on the system. We keep maximum of 5
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * log files. With the new session the files are shifted to next number
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and if the last file {logfilename}.5 exist, it will be overwritten
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * with {logfilename}.4.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (debug) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i = LOG_FILE_CNT - 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (i >= 0) {
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar fname = mk_pathname(LOG_FNAME, lpath, i);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strncpy(oldfname, fname, PATH_MAX);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar if (stat64(oldfname, &st) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i--;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar fname = mk_pathname(LOG_FNAME, lpath, i + 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rename(oldfname, fname))
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr,
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl "Could not rename %s to %s: %s\n",
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl oldfname, fname, strerror(errno));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i--;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar fname = mk_pathname(LOG_FNAME, lpath, 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Append only if debug is not enable.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (debug)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode = "w";
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mode = "a";
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (openlogfile(fname, mode));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ndmp_log_close_file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Close the log file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_log_close_file(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (logfp != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(logfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar logfp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) mutex_destroy(&log_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_log(ulong_t priority, char *ndmp_log_info, char *fmt, ...)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int c;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar va_list args;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *f, *b;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char ndmp_log_buf[PATH_MAX+KILOBYTE];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char ndmp_syslog_buf[PATH_MAX+KILOBYTE];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char buf[PATH_MAX+KILOBYTE];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *errstr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if ((priority == LOG_DEBUG) && !debug)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&log_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (priority > 7)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priority = LOG_ERR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar va_start(args, fmt);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Replace text error messages if fmt contains %m */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar b = buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar f = fmt;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (((c = *f++) != '\0') && (c != '\n') &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (b < &buf[PATH_MAX+KILOBYTE])) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (c != '%') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *b++ = c;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((c = *f++) != 'm') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *b++ = '%';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *b++ = c;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((errstr = strerror(errno)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(b, &buf[PATH_MAX+KILOBYTE] - b,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "error %d", errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((*errstr != '\0') &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (b < &buf[PATH_MAX+KILOBYTE])) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*errstr == '%') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strncpy(b, "%%", 2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar b += 2;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *b++ = *errstr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar errstr++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *b = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar b += strlen(b);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *b = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED variable format specifier */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) vsnprintf(ndmp_syslog_buf, sizeof (ndmp_syslog_buf), buf, args);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar va_end(args);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Send all logs other than debug, to syslog log file. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (priority != LOG_DEBUG)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar syslog(priority, "%s", ndmp_syslog_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* ndmp_log_buf will have priority string and log info also */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(ndmp_log_buf, sizeof (ndmp_log_buf), "%s: %s:%s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priority_str[priority], ndmp_log_info, ndmp_syslog_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (logfp != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar log_append(ndmp_log_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl /* if ndmpd is running in foreground print log message to stderr */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (log_to_stderr)
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr, "%s\n", ndmp_log_buf);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&log_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}