xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_log.c (revision 8800:dbcc21c0ec0f)
17917SReza.Sabdar@Sun.COM /*
2*8800SReza.Sabdar@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37917SReza.Sabdar@Sun.COM  * Use is subject to license terms.
47917SReza.Sabdar@Sun.COM  */
57917SReza.Sabdar@Sun.COM 
67917SReza.Sabdar@Sun.COM /*
77917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
87917SReza.Sabdar@Sun.COM  *
97917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
107917SReza.Sabdar@Sun.COM  *
117917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
127917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
137917SReza.Sabdar@Sun.COM  * are met:
147917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
157917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
167917SReza.Sabdar@Sun.COM  *
177917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
187917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
197917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
207917SReza.Sabdar@Sun.COM  *	  distribution.
217917SReza.Sabdar@Sun.COM  *
227917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
237917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
247917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
257917SReza.Sabdar@Sun.COM  *	  permission.
267917SReza.Sabdar@Sun.COM  *
277917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
287917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
297917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
307917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
317917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
327917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
337917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
347917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
357917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
367917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
377917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
387917SReza.Sabdar@Sun.COM  */
397917SReza.Sabdar@Sun.COM /* Copyright (c) 2007, The Storage Networking Industry Association. */
407917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
417917SReza.Sabdar@Sun.COM 
427917SReza.Sabdar@Sun.COM #include <errno.h>
437917SReza.Sabdar@Sun.COM #include <limits.h>
447917SReza.Sabdar@Sun.COM #include <stdarg.h>
457917SReza.Sabdar@Sun.COM #include <stdio.h>
467917SReza.Sabdar@Sun.COM #include <stdlib.h>
477917SReza.Sabdar@Sun.COM #include <syslog.h>
487917SReza.Sabdar@Sun.COM #include <time.h>
497917SReza.Sabdar@Sun.COM #include <string.h>
507917SReza.Sabdar@Sun.COM #include <sys/stat.h>
517917SReza.Sabdar@Sun.COM #include <unistd.h>
52*8800SReza.Sabdar@Sun.COM #include <libgen.h>
537917SReza.Sabdar@Sun.COM #include <pthread.h>
547917SReza.Sabdar@Sun.COM #include <errno.h>
557917SReza.Sabdar@Sun.COM #include "ndmpd_log.h"
567917SReza.Sabdar@Sun.COM #include "ndmpd.h"
577917SReza.Sabdar@Sun.COM #include "ndmpd_common.h"
587917SReza.Sabdar@Sun.COM 
597917SReza.Sabdar@Sun.COM #define	LOG_FNAME	"ndmplog.%d"
607917SReza.Sabdar@Sun.COM #define	LOG_FILE_CNT	5
617917SReza.Sabdar@Sun.COM #define	LOG_FILE_SIZE	4 * 1024 * 1024
627917SReza.Sabdar@Sun.COM #define	LOG_SIZE_INT	256
637917SReza.Sabdar@Sun.COM 
647917SReza.Sabdar@Sun.COM static boolean_t debug_level = 0;
657917SReza.Sabdar@Sun.COM static FILE *logfp;
667917SReza.Sabdar@Sun.COM static int ndmp_synclog = 1;
677917SReza.Sabdar@Sun.COM 
687917SReza.Sabdar@Sun.COM 
697917SReza.Sabdar@Sun.COM /*
707917SReza.Sabdar@Sun.COM  * Since we use buffered file I/O for log file, the thread may lose CPU.
717917SReza.Sabdar@Sun.COM  * At this time, another thread can destroy the contents of the buffer
727917SReza.Sabdar@Sun.COM  * that must be written to the log file.  The following mutex is used
737917SReza.Sabdar@Sun.COM  * to allow only one thread to write into the log file.
747917SReza.Sabdar@Sun.COM  */
757917SReza.Sabdar@Sun.COM mutex_t log_lock;
767917SReza.Sabdar@Sun.COM mutex_t idx_lock;
777917SReza.Sabdar@Sun.COM 
787917SReza.Sabdar@Sun.COM static char *priority_str[] = {
797917SReza.Sabdar@Sun.COM 	"EMERGENCY",
807917SReza.Sabdar@Sun.COM 	"ALERT",
817917SReza.Sabdar@Sun.COM 	"CRITICAL",
827917SReza.Sabdar@Sun.COM 	"ERROR",
837917SReza.Sabdar@Sun.COM 	"WARNING",
847917SReza.Sabdar@Sun.COM 	"NOTICE",
857917SReza.Sabdar@Sun.COM 	"INFO",
867917SReza.Sabdar@Sun.COM 	"DEBUG",
877917SReza.Sabdar@Sun.COM };
887917SReza.Sabdar@Sun.COM 
897917SReza.Sabdar@Sun.COM 
907917SReza.Sabdar@Sun.COM /*
917917SReza.Sabdar@Sun.COM  * mk_pathname
927917SReza.Sabdar@Sun.COM  *
937917SReza.Sabdar@Sun.COM  * Append the NDMP working directory path to the specified file
947917SReza.Sabdar@Sun.COM  */
957917SReza.Sabdar@Sun.COM static char *
mk_pathname(char * fname,char * path,int idx)96*8800SReza.Sabdar@Sun.COM mk_pathname(char *fname, char *path, int idx)
977917SReza.Sabdar@Sun.COM {
987917SReza.Sabdar@Sun.COM 	static char buf[PATH_MAX];
997917SReza.Sabdar@Sun.COM 	static char name[NAME_MAX];
100*8800SReza.Sabdar@Sun.COM 	char *fmt;
1017917SReza.Sabdar@Sun.COM 	int len;
1027917SReza.Sabdar@Sun.COM 
1037917SReza.Sabdar@Sun.COM 	len = strlen(path);
1047917SReza.Sabdar@Sun.COM 	fmt = (path[len - 1] == '/') ? "%s%s" : "%s/%s";
1057917SReza.Sabdar@Sun.COM 
1067917SReza.Sabdar@Sun.COM 	/* LINTED variable format specifier */
1077917SReza.Sabdar@Sun.COM 	(void) snprintf(name, NAME_MAX, fname, idx);
1087917SReza.Sabdar@Sun.COM 
1097917SReza.Sabdar@Sun.COM 	/* LINTED variable format specifier */
1107917SReza.Sabdar@Sun.COM 	(void) snprintf(buf, PATH_MAX, fmt, path, name);
1117917SReza.Sabdar@Sun.COM 	return (buf);
1127917SReza.Sabdar@Sun.COM }
1137917SReza.Sabdar@Sun.COM 
1147917SReza.Sabdar@Sun.COM 
1157917SReza.Sabdar@Sun.COM /*
1167917SReza.Sabdar@Sun.COM  * openlogfile
1177917SReza.Sabdar@Sun.COM  *
1187917SReza.Sabdar@Sun.COM  * Open the NDMP log file
1197917SReza.Sabdar@Sun.COM  */
1207917SReza.Sabdar@Sun.COM static int
openlogfile(char * fname,char * mode)1217917SReza.Sabdar@Sun.COM openlogfile(char *fname, char *mode)
1227917SReza.Sabdar@Sun.COM {
1237917SReza.Sabdar@Sun.COM 	int rv;
1247917SReza.Sabdar@Sun.COM 
1257917SReza.Sabdar@Sun.COM 	if (fname == NULL || *fname == '\0' || mode == NULL || *mode == '\0')
1267917SReza.Sabdar@Sun.COM 		return (-1);
1277917SReza.Sabdar@Sun.COM 
1287917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&log_lock);
1297917SReza.Sabdar@Sun.COM 	rv = 0;
1307917SReza.Sabdar@Sun.COM 	if (logfp != NULL) {
1317917SReza.Sabdar@Sun.COM 		NDMP_LOG(LOG_DEBUG, "Log file already opened.");
1327917SReza.Sabdar@Sun.COM 		rv = -1;
1337917SReza.Sabdar@Sun.COM 	} else if ((logfp = fopen(fname, mode)) == NULL) {
1347917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Error opening logfile %s, %m.", fname);
1357917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Using system log for logging.");
1367917SReza.Sabdar@Sun.COM 		rv = -1;
1377917SReza.Sabdar@Sun.COM 	}
1387917SReza.Sabdar@Sun.COM 
1397917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&log_lock);
1407917SReza.Sabdar@Sun.COM 	return (rv);
1417917SReza.Sabdar@Sun.COM }
1427917SReza.Sabdar@Sun.COM 
1437917SReza.Sabdar@Sun.COM 
1447917SReza.Sabdar@Sun.COM /*
1457917SReza.Sabdar@Sun.COM  * log_write_cur_time
1467917SReza.Sabdar@Sun.COM  *
1477917SReza.Sabdar@Sun.COM  * Add the current time for each log entry
1487917SReza.Sabdar@Sun.COM  */
1497917SReza.Sabdar@Sun.COM static void
log_write_cur_time(void)1507917SReza.Sabdar@Sun.COM log_write_cur_time(void)
1517917SReza.Sabdar@Sun.COM {
1527917SReza.Sabdar@Sun.COM 	struct tm tm;
1537917SReza.Sabdar@Sun.COM 	time_t secs;
1547917SReza.Sabdar@Sun.COM 
1557917SReza.Sabdar@Sun.COM 	secs = time(NULL);
1567917SReza.Sabdar@Sun.COM 	(void) localtime_r(&secs, &tm);
1577917SReza.Sabdar@Sun.COM 	(void) fprintf(logfp, "%2d/%02d %2d:%02d:%02d ",
1587917SReza.Sabdar@Sun.COM 	    tm.tm_mon + 1, tm.tm_mday,
1597917SReza.Sabdar@Sun.COM 	    tm.tm_hour, tm.tm_min, tm.tm_sec);
1607917SReza.Sabdar@Sun.COM }
1617917SReza.Sabdar@Sun.COM 
1627917SReza.Sabdar@Sun.COM 
1637917SReza.Sabdar@Sun.COM /*
1647917SReza.Sabdar@Sun.COM  * add_newline
1657917SReza.Sabdar@Sun.COM  *
1667917SReza.Sabdar@Sun.COM  * The new line at the end of each log
1677917SReza.Sabdar@Sun.COM  */
1687917SReza.Sabdar@Sun.COM static void
add_newline(char * fmt)1697917SReza.Sabdar@Sun.COM add_newline(char *fmt)
1707917SReza.Sabdar@Sun.COM {
1717917SReza.Sabdar@Sun.COM 	if (fmt[strlen(fmt) - 1] != '\n')
1727917SReza.Sabdar@Sun.COM 		(void) fputc('\n', logfp);
1737917SReza.Sabdar@Sun.COM }
1747917SReza.Sabdar@Sun.COM 
1757917SReza.Sabdar@Sun.COM 
1767917SReza.Sabdar@Sun.COM /*
1777917SReza.Sabdar@Sun.COM  * log_append
1787917SReza.Sabdar@Sun.COM  *
1797917SReza.Sabdar@Sun.COM  * Append the message to the end of the log
1807917SReza.Sabdar@Sun.COM  */
1817917SReza.Sabdar@Sun.COM static void
log_append(char * msg)1827917SReza.Sabdar@Sun.COM log_append(char *msg)
1837917SReza.Sabdar@Sun.COM {
1847917SReza.Sabdar@Sun.COM 	log_write_cur_time();
1857917SReza.Sabdar@Sun.COM 	(void) fwrite(msg, 1, strlen(msg), logfp);
1867917SReza.Sabdar@Sun.COM 	add_newline(msg);
1877917SReza.Sabdar@Sun.COM 	if (ndmp_synclog)
1887917SReza.Sabdar@Sun.COM 		(void) fflush(logfp);
1897917SReza.Sabdar@Sun.COM }
1907917SReza.Sabdar@Sun.COM 
1917917SReza.Sabdar@Sun.COM 
1927917SReza.Sabdar@Sun.COM /*
1937917SReza.Sabdar@Sun.COM  * ndmp_log_openfile
1947917SReza.Sabdar@Sun.COM  *
1957917SReza.Sabdar@Sun.COM  * Open the log file either for append or write mode.
1967917SReza.Sabdar@Sun.COM  */
1977917SReza.Sabdar@Sun.COM int
ndmp_log_open_file(void)1987917SReza.Sabdar@Sun.COM ndmp_log_open_file(void)
1997917SReza.Sabdar@Sun.COM {
2007917SReza.Sabdar@Sun.COM 	char *fname, *mode;
2017917SReza.Sabdar@Sun.COM 	char oldfname[PATH_MAX];
202*8800SReza.Sabdar@Sun.COM 	char *lpath;
203*8800SReza.Sabdar@Sun.COM 	struct stat64 st;
2047917SReza.Sabdar@Sun.COM 	int i;
2057917SReza.Sabdar@Sun.COM 
206*8800SReza.Sabdar@Sun.COM 	/* Create the debug path if doesn't exist */
207*8800SReza.Sabdar@Sun.COM 	lpath = ndmpd_get_prop(NDMP_DEBUG_PATH);
208*8800SReza.Sabdar@Sun.COM 	if ((lpath == NULL) || (*lpath == NULL))
209*8800SReza.Sabdar@Sun.COM 		lpath = "/var/ndmp";
210*8800SReza.Sabdar@Sun.COM 
211*8800SReza.Sabdar@Sun.COM 	if (stat64(lpath, &st) < 0) {
212*8800SReza.Sabdar@Sun.COM 		if (mkdirp(lpath, 0755) < 0) {
213*8800SReza.Sabdar@Sun.COM 			NDMP_LOG(LOG_ERR, "Could not create log path %s: %m.",
214*8800SReza.Sabdar@Sun.COM 			    lpath);
215*8800SReza.Sabdar@Sun.COM 			lpath = "/var";
216*8800SReza.Sabdar@Sun.COM 		}
217*8800SReza.Sabdar@Sun.COM 	}
218*8800SReza.Sabdar@Sun.COM 
2197917SReza.Sabdar@Sun.COM 	/*
2207917SReza.Sabdar@Sun.COM 	 * NDMP log file name will be {logfilename}.0 to {logfilename}.5, where
2217917SReza.Sabdar@Sun.COM 	 * {logfilename}.0 will always be the latest and the {logfilename}.5
2227917SReza.Sabdar@Sun.COM 	 * will be the oldest available file on the system. We keep maximum of 5
2237917SReza.Sabdar@Sun.COM 	 * log files. With the new session the files are shifted to next number
2247917SReza.Sabdar@Sun.COM 	 * and if the last file {logfilename}.5 exist, it will be overwritten
2257917SReza.Sabdar@Sun.COM 	 * with {logfilename}.4.
2267917SReza.Sabdar@Sun.COM 	 */
2277917SReza.Sabdar@Sun.COM 	if (get_debug_level()) {
2287917SReza.Sabdar@Sun.COM 		i = LOG_FILE_CNT - 1;
2297917SReza.Sabdar@Sun.COM 		while (i >= 0) {
230*8800SReza.Sabdar@Sun.COM 			fname = mk_pathname(LOG_FNAME, lpath, i);
2317917SReza.Sabdar@Sun.COM 			(void) strncpy(oldfname, fname, PATH_MAX);
232*8800SReza.Sabdar@Sun.COM 			if (stat64(oldfname, &st) == -1) {
2337917SReza.Sabdar@Sun.COM 				i--;
2347917SReza.Sabdar@Sun.COM 				continue;
2357917SReza.Sabdar@Sun.COM 			}
2367917SReza.Sabdar@Sun.COM 
237*8800SReza.Sabdar@Sun.COM 			fname = mk_pathname(LOG_FNAME, lpath, i + 1);
2387917SReza.Sabdar@Sun.COM 			if (rename(oldfname, fname))
2397917SReza.Sabdar@Sun.COM 				syslog(LOG_DEBUG,
2407917SReza.Sabdar@Sun.COM 				    "Could not rename from %s to %s",
2417917SReza.Sabdar@Sun.COM 				    oldfname, fname);
2427917SReza.Sabdar@Sun.COM 			i--;
2437917SReza.Sabdar@Sun.COM 		}
2447917SReza.Sabdar@Sun.COM 	}
2457917SReza.Sabdar@Sun.COM 
246*8800SReza.Sabdar@Sun.COM 	fname = mk_pathname(LOG_FNAME, lpath, 0);
2477917SReza.Sabdar@Sun.COM 
2487917SReza.Sabdar@Sun.COM 	/*
2497917SReza.Sabdar@Sun.COM 	 * Append only if debug is not enable.
2507917SReza.Sabdar@Sun.COM 	 */
2517917SReza.Sabdar@Sun.COM 	if (get_debug_level())
2527917SReza.Sabdar@Sun.COM 		mode = "w";
2537917SReza.Sabdar@Sun.COM 	else
2547917SReza.Sabdar@Sun.COM 		mode = "a";
2557917SReza.Sabdar@Sun.COM 
2567917SReza.Sabdar@Sun.COM 	return (openlogfile(fname, mode));
2577917SReza.Sabdar@Sun.COM }
2587917SReza.Sabdar@Sun.COM 
2597917SReza.Sabdar@Sun.COM /*
2607917SReza.Sabdar@Sun.COM  * ndmp_log_close_file
2617917SReza.Sabdar@Sun.COM  *
2627917SReza.Sabdar@Sun.COM  * Close the log file
2637917SReza.Sabdar@Sun.COM  */
2647917SReza.Sabdar@Sun.COM void
ndmp_log_close_file(void)2657917SReza.Sabdar@Sun.COM ndmp_log_close_file(void)
2667917SReza.Sabdar@Sun.COM {
2677917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&log_lock);
2687917SReza.Sabdar@Sun.COM 	if (logfp != NULL) {
2697917SReza.Sabdar@Sun.COM 		(void) fclose(logfp);
2707917SReza.Sabdar@Sun.COM 		logfp = NULL;
2717917SReza.Sabdar@Sun.COM 	}
2727917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&log_lock);
2737917SReza.Sabdar@Sun.COM }
2747917SReza.Sabdar@Sun.COM 
2757917SReza.Sabdar@Sun.COM /*
2767917SReza.Sabdar@Sun.COM  * set_debug_level
2777917SReza.Sabdar@Sun.COM  *
2787917SReza.Sabdar@Sun.COM  * Sets the current debug level.
2797917SReza.Sabdar@Sun.COM  * Parameters:
2807917SReza.Sabdar@Sun.COM  *   level (input) - new debug level.
2817917SReza.Sabdar@Sun.COM  *
2827917SReza.Sabdar@Sun.COM  * Returns:
2837917SReza.Sabdar@Sun.COM  *   old debug level.
2847917SReza.Sabdar@Sun.COM  */
2857917SReza.Sabdar@Sun.COM boolean_t
set_debug_level(boolean_t level)2867917SReza.Sabdar@Sun.COM set_debug_level(boolean_t level)
2877917SReza.Sabdar@Sun.COM {
2887917SReza.Sabdar@Sun.COM 	boolean_t old = debug_level;
2897917SReza.Sabdar@Sun.COM 
2907917SReza.Sabdar@Sun.COM 	debug_level = level;
2917917SReza.Sabdar@Sun.COM 	return (old);
2927917SReza.Sabdar@Sun.COM }
2937917SReza.Sabdar@Sun.COM 
2947917SReza.Sabdar@Sun.COM 
2957917SReza.Sabdar@Sun.COM /*
2967917SReza.Sabdar@Sun.COM  * get_debug_level
2977917SReza.Sabdar@Sun.COM  *
2987917SReza.Sabdar@Sun.COM  * Returns the current debug level.
2997917SReza.Sabdar@Sun.COM  *
3007917SReza.Sabdar@Sun.COM  * Parameters:
3017917SReza.Sabdar@Sun.COM  *   None.
3027917SReza.Sabdar@Sun.COM  *
3037917SReza.Sabdar@Sun.COM  * Returns:
3047917SReza.Sabdar@Sun.COM  *   debug level.
3057917SReza.Sabdar@Sun.COM  */
3067917SReza.Sabdar@Sun.COM boolean_t
get_debug_level(void)3077917SReza.Sabdar@Sun.COM get_debug_level(void)
3087917SReza.Sabdar@Sun.COM {
3097917SReza.Sabdar@Sun.COM 	return (debug_level);
3107917SReza.Sabdar@Sun.COM }
3117917SReza.Sabdar@Sun.COM 
3127917SReza.Sabdar@Sun.COM void
ndmp_log(ulong_t priority,char * ndmp_log_info,char * fmt,...)3137917SReza.Sabdar@Sun.COM ndmp_log(ulong_t priority, char *ndmp_log_info, char *fmt, ...)
3147917SReza.Sabdar@Sun.COM {
3157917SReza.Sabdar@Sun.COM 	int c;
3167917SReza.Sabdar@Sun.COM 	va_list args;
3177917SReza.Sabdar@Sun.COM 	char *f, *b;
3187917SReza.Sabdar@Sun.COM 	char ndmp_log_buf[PATH_MAX+KILOBYTE];
3197917SReza.Sabdar@Sun.COM 	char ndmp_syslog_buf[PATH_MAX+KILOBYTE];
3207917SReza.Sabdar@Sun.COM 	char buf[PATH_MAX+KILOBYTE];
3217917SReza.Sabdar@Sun.COM 	char *errstr;
3227917SReza.Sabdar@Sun.COM 
3237917SReza.Sabdar@Sun.COM 	if ((priority == LOG_DEBUG) && (debug_level == FALSE))
3247917SReza.Sabdar@Sun.COM 		return;
3257917SReza.Sabdar@Sun.COM 
3267917SReza.Sabdar@Sun.COM 	(void) mutex_lock(&log_lock);
3277917SReza.Sabdar@Sun.COM 
3287917SReza.Sabdar@Sun.COM 	if (priority > 7)
3297917SReza.Sabdar@Sun.COM 		priority = LOG_ERR;
3307917SReza.Sabdar@Sun.COM 
3317917SReza.Sabdar@Sun.COM 	va_start(args, fmt);
3327917SReza.Sabdar@Sun.COM 	/* Replace text error messages if fmt contains %m */
3337917SReza.Sabdar@Sun.COM 	b = buf;
3347917SReza.Sabdar@Sun.COM 	f = fmt;
3357917SReza.Sabdar@Sun.COM 	while (((c = *f++) != '\0') && (c != '\n') &&
3367917SReza.Sabdar@Sun.COM 	    (b < &buf[PATH_MAX+KILOBYTE])) {
3377917SReza.Sabdar@Sun.COM 		if (c != '%') {
3387917SReza.Sabdar@Sun.COM 			*b++ = c;
3397917SReza.Sabdar@Sun.COM 			continue;
3407917SReza.Sabdar@Sun.COM 		}
3417917SReza.Sabdar@Sun.COM 		if ((c = *f++) != 'm') {
3427917SReza.Sabdar@Sun.COM 			*b++ = '%';
3437917SReza.Sabdar@Sun.COM 			*b++ = c;
3447917SReza.Sabdar@Sun.COM 			continue;
3457917SReza.Sabdar@Sun.COM 		}
3467917SReza.Sabdar@Sun.COM 
3477917SReza.Sabdar@Sun.COM 		if ((errstr = strerror(errno)) == NULL) {
3487917SReza.Sabdar@Sun.COM 			(void) snprintf(b, &buf[PATH_MAX+KILOBYTE] - b,
3497917SReza.Sabdar@Sun.COM 			    "error %d", errno);
3507917SReza.Sabdar@Sun.COM 		} else {
3517917SReza.Sabdar@Sun.COM 			while ((*errstr != '\0') &&
3527917SReza.Sabdar@Sun.COM 			    (b < &buf[PATH_MAX+KILOBYTE])) {
3537917SReza.Sabdar@Sun.COM 				if (*errstr == '%') {
3547917SReza.Sabdar@Sun.COM 					(void) strncpy(b, "%%", 2);
3557917SReza.Sabdar@Sun.COM 					b += 2;
3567917SReza.Sabdar@Sun.COM 				} else {
3577917SReza.Sabdar@Sun.COM 					*b++ = *errstr;
3587917SReza.Sabdar@Sun.COM 				}
3597917SReza.Sabdar@Sun.COM 				errstr++;
3607917SReza.Sabdar@Sun.COM 			}
3617917SReza.Sabdar@Sun.COM 			*b = '\0';
3627917SReza.Sabdar@Sun.COM 		}
3637917SReza.Sabdar@Sun.COM 		b += strlen(b);
3647917SReza.Sabdar@Sun.COM 	}
3657917SReza.Sabdar@Sun.COM 	*b = '\0';
3667917SReza.Sabdar@Sun.COM 
3677917SReza.Sabdar@Sun.COM 	/* LINTED variable format specifier */
3687917SReza.Sabdar@Sun.COM 	(void) vsnprintf(ndmp_syslog_buf, sizeof (ndmp_syslog_buf), buf, args);
3697917SReza.Sabdar@Sun.COM 	va_end(args);
3707917SReza.Sabdar@Sun.COM 
3717917SReza.Sabdar@Sun.COM 	/* Send all logs other than debug, to syslog log file. */
3727917SReza.Sabdar@Sun.COM 	if (priority != LOG_DEBUG)
3737917SReza.Sabdar@Sun.COM 		syslog(priority, "%s", ndmp_syslog_buf);
3747917SReza.Sabdar@Sun.COM 
3757917SReza.Sabdar@Sun.COM 	/* ndmp_log_buf will have priority string and log info also */
3767917SReza.Sabdar@Sun.COM 	(void) snprintf(ndmp_log_buf, sizeof (ndmp_log_buf), "%s: %s:%s",
3777917SReza.Sabdar@Sun.COM 	    priority_str[priority], ndmp_log_info, ndmp_syslog_buf);
3787917SReza.Sabdar@Sun.COM 
3797917SReza.Sabdar@Sun.COM 	if (logfp != NULL)
3807917SReza.Sabdar@Sun.COM 		log_append(ndmp_log_buf);
3817917SReza.Sabdar@Sun.COM 
3827917SReza.Sabdar@Sun.COM 	(void) mutex_unlock(&log_lock);
3837917SReza.Sabdar@Sun.COM }
384