1 /*
2 * Copyright 2004-2012 Red Hat, Inc.
3 *
4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions
6 * of the GNU General Public License v2 or (at your option) any later version.
7 */
8
9 #include "dlm_daemon.h"
10
11 static int syslog_facility;
12 static int syslog_priority;
13 static int logfile_priority;
14 static char logfile[PATH_MAX];
15 static FILE *logfile_fp;
16
17 /* logfile_priority is the only one of these options that
18 can be controlled from command line, environment variable
19 and dynamic setting.
20 */
21 void set_logfile_priority(void)
22 {
23 if (opt(debug_logfile_ind))
24 logfile_priority = LOG_DEBUG;
25 else
26 logfile_priority = DEFAULT_LOGFILE_PRIORITY;
27 }
28
29 void init_logging(void)
30 {
31 mode_t old_umask;
32 int rv;
33
34 syslog_facility = DEFAULT_SYSLOG_FACILITY;
35 syslog_priority = DEFAULT_SYSLOG_PRIORITY;
36 logfile_priority = DEFAULT_LOGFILE_PRIORITY;
37 strcpy(logfile, DEFAULT_LOGFILE);
38
39 set_logfile_priority();
40
41 old_umask = umask(0077);
42 rv = mkdir(SYS_VARDIR, 0700);
|
(1) Event cond_false: |
Condition "rv < 0", taking false branch. |
43 if (rv < 0 && errno != EEXIST) {
44 umask(old_umask);
45 goto skip_logfile;
|
(2) Event if_end: |
End of if statement. |
46 }
47
48 rv = mkdir(SYS_LOGDIR, 0700);
|
(3) Event cond_false: |
Condition "rv < 0", taking false branch. |
49 if (rv < 0 && errno != EEXIST) {
50 umask(old_umask);
51 goto skip_logfile;
|
(4) Event if_end: |
End of if statement. |
52 }
53
54 rv = mkdir(LOGDIR, 0700);
|
(5) Event cond_false: |
Condition "rv < 0", taking false branch. |
55 if (rv < 0 && errno != EEXIST) {
56 umask(old_umask);
57 goto skip_logfile;
|
(6) Event if_end: |
End of if statement. |
58 }
59 umask(old_umask);
60
|
(7) Event cond_true: |
Condition "logfile[0]", taking true branch. |
61 if (logfile[0]) {
62 logfile_fp = fopen(logfile, "a+");
|
(8) Event cond_true: |
Condition "logfile_fp != NULL", taking true branch. |
63 if (logfile_fp != NULL) {
64 int fd = fileno(logfile_fp);
|
(9) Event check_return: |
Calling "fcntl(fd, 2, fcntl(fd, 1, 0) | 1)" without checking return value. This library function may fail and return an error code. |
65 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
66 }
67 }
68
69 skip_logfile:
70 openlog(DAEMON_NAME, LOG_CONS | LOG_PID, syslog_facility);
71 }
72
73 void close_logging(void)
74 {
75 closelog();
76 if (logfile_fp)
77 fclose(logfile_fp);
78 }
79
80 #define NAME_ID_SIZE 32
81 #define LOG_STR_LEN 512
82 static char log_str[LOG_STR_LEN];
83
84 static char log_dump[LOG_DUMP_SIZE];
85 static unsigned int log_point;
86 static unsigned int log_wrap;
87
88 static char log_dump_plock[LOG_DUMP_SIZE];
89 static unsigned int log_point_plock;
90 static unsigned int log_wrap_plock;
91
92 static void log_copy(char *buf, int *len, char *log_buf,
93 unsigned int *point, unsigned int *wrap)
94 {
95 unsigned int p = *point;
96 unsigned int w = *wrap;
97 int tail_len;
98
99 if (!w && !p) {
100 *len = 0;
101 } else if (*wrap) {
102 tail_len = LOG_DUMP_SIZE - p;
103 memcpy(buf, log_buf + p, tail_len);
104 if (p)
105 memcpy(buf+tail_len, log_buf, p);
106 *len = LOG_DUMP_SIZE;
107 } else {
108 memcpy(buf, log_buf, p-1);
109 *len = p-1;
110 }
111 }
112
113 void copy_log_dump(char *buf, int *len)
114 {
115 log_copy(buf, len, log_dump, &log_point, &log_wrap);
116 }
117
118 void copy_log_dump_plock(char *buf, int *len)
119 {
120 log_copy(buf, len, log_dump_plock, &log_point_plock, &log_wrap_plock);
121 }
122
123 static void log_save_str(int len, char *log_buf, unsigned int *point,
124 unsigned int *wrap)
125 {
126 unsigned int p = *point;
127 unsigned int w = *wrap;
128 int i;
129
130 if (len < LOG_DUMP_SIZE - p) {
131 memcpy(log_buf + p, log_str, len);
132 p += len;
133
134 if (p == LOG_DUMP_SIZE) {
135 p = 0;
136 w = 1;
137 }
138 goto out;
139 }
140
141 for (i = 0; i < len; i++) {
142 log_buf[p++] = log_str[i];
143
144 if (p == LOG_DUMP_SIZE) {
145 p = 0;
146 w = 1;
147 }
148 }
149 out:
150 *point = p;
151 *wrap = w;
152 }
153
154 void log_level(const char *name_in, uint32_t level_in, const char *fmt, ...)
155 {
156 va_list ap;
157 char name[NAME_ID_SIZE + 2];
158 uint32_t level = level_in & 0x0000FFFF;
159 uint32_t extra = level_in & 0xFFFF0000;
160 int ret, pos = 0;
161 int len = LOG_STR_LEN - 2;
162 int namelen = 0;
163 int plock = extra & LOG_PLOCK;
164
165 memset(name, 0, sizeof(name));
166
167 if (name_in) {
168 namelen = snprintf(name, NAME_ID_SIZE + 1, "%s", name_in);
169 if (namelen > NAME_ID_SIZE)
170 namelen = NAME_ID_SIZE;
171 name[namelen] = ' ';
172 name[namelen+1] = '\0';
173 }
174
175 ret = snprintf(log_str + pos, len - pos, "%llu %s",
176 (unsigned long long)monotime(), name);
177
178 pos += ret;
179
180 va_start(ap, fmt);
181 ret = vsnprintf(log_str + pos, len - pos, fmt, ap);
182 va_end(ap);
183
184 if (ret >= len - pos)
185 pos = len - 1;
186 else
187 pos += ret;
188
189 log_str[pos++] = '\n';
190 log_str[pos++] = '\0';
191
192 if (level < LOG_NONE)
193 log_save_str(pos - 1, log_dump, &log_point, &log_wrap);
194 if (plock)
195 log_save_str(pos - 1, log_dump_plock, &log_point_plock, &log_wrap_plock);
196
197 if (level <= syslog_priority)
198 syslog(level, "%s", log_str);
199
200 if (level <= logfile_priority && logfile_fp) {
201 time_t logtime = time(NULL);
202 char tbuf[64];
203 strftime(tbuf, sizeof(tbuf), "%b %d %T", localtime(&logtime));
204 fprintf(logfile_fp, "%s %s", tbuf, log_str);
205 fflush(logfile_fp);
206 }
207
208 if (!dlm_options[daemon_debug_ind].use_int)
209 return;
210
211 if ((level < LOG_NONE) || (plock && opt(plock_debug_ind)))
212 fprintf(stderr, "%s", log_str);
213 }
214
215