]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/log.c
spelling: userns
[mirror_lxc.git] / src / lxc / log.c
CommitLineData
e0b4037d
DL
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Cedric Le Goater <legoater@free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e0b4037d 22 */
b4c42474 23
d38dd64a
CB
24#ifndef _GNU_SOURCE
25#define _GNU_SOURCE 1
26#endif
65a9df89 27#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
0ad19a3f 28#include <errno.h>
d38dd64a 29#include <fcntl.h>
65a9df89 30#include <inttypes.h>
cb8c5720 31#include <limits.h>
858377e4 32#include <pthread.h>
d38dd64a 33#include <stdint.h>
64c57ea1 34#include <stdio.h>
cb8c5720 35#include <stdlib.h>
d38dd64a
CB
36#include <string.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <syslog.h>
40#include <unistd.h>
cb8c5720 41
28f602ff 42#include "caps.h"
d38dd64a
CB
43#include "config.h"
44#include "log.h"
73b910a3 45#include "lxccontainer.h"
d38dd64a 46#include "utils.h"
cb8c5720 47
9de31d5a
CB
48#ifndef HAVE_STRLCPY
49#include "include/strlcpy.h"
50#endif
51
5c7bfc02 52#if HAVE_DLOG
53#include <dlog.h>
54
55#undef LOG_TAG
56#define LOG_TAG "LXC"
57#endif
58
c57dbb96
CB
59/* We're logging in seconds and nanoseconds. Assuming that the underlying
60 * datatype is currently at maximum a 64bit integer, we have a date string that
61 * is of maximum length (2^64 - 1) * 2 = (21 + 21) = 42.
62 */
3a2c65f8 63#define LXC_LOG_TIME_SIZE ((INTTYPE_TO_STRLEN(uint64_t)) * 2)
6a22e862 64
9f4f402a 65int lxc_log_fd = -1;
64c57ea1 66static int syslog_enable = 0;
858377e4
SH
67int lxc_quiet_specified;
68int lxc_log_use_global_fd;
69static int lxc_loglevel_specified;
70
6b9f3917 71static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
ab1bf971 72static char *log_fname = NULL;
64c57ea1 73static char *log_vmname = NULL;
cb8c5720 74
ac2cecc4 75lxc_log_define(log, lxc);
cb8c5720 76
64c57ea1
BD
77static int lxc_log_priority_to_syslog(int priority)
78{
79 switch (priority) {
4b73005c 80 case LXC_LOG_LEVEL_FATAL:
64c57ea1 81 return LOG_EMERG;
4b73005c 82 case LXC_LOG_LEVEL_ALERT:
64c57ea1 83 return LOG_ALERT;
4b73005c 84 case LXC_LOG_LEVEL_CRIT:
64c57ea1 85 return LOG_CRIT;
4b73005c 86 case LXC_LOG_LEVEL_ERROR:
64c57ea1 87 return LOG_ERR;
4b73005c 88 case LXC_LOG_LEVEL_WARN:
64c57ea1 89 return LOG_WARNING;
4b73005c
CB
90 case LXC_LOG_LEVEL_NOTICE:
91 case LXC_LOG_LEVEL_NOTSET:
64c57ea1 92 return LOG_NOTICE;
4b73005c 93 case LXC_LOG_LEVEL_INFO:
64c57ea1 94 return LOG_INFO;
4b73005c
CB
95 case LXC_LOG_LEVEL_TRACE:
96 case LXC_LOG_LEVEL_DEBUG:
64c57ea1
BD
97 return LOG_DEBUG;
98 }
99
100 /* Not reached */
101 return LOG_NOTICE;
102}
103
8178adc6 104static const char *lxc_log_get_container_name()
105{
106#ifndef NO_LXC_CONF
107 if (current_config && !log_vmname)
108 return current_config->name;
109#endif
110
111 return log_vmname;
112}
113
114static char *lxc_log_get_va_msg(struct lxc_log_event *event)
64c57ea1
BD
115{
116 char *msg;
117 int rc, len;
118 va_list args;
c7b17051 119
8178adc6 120 if (!event)
121 return NULL;
64c57ea1
BD
122
123 va_copy(args, *event->vap);
124 len = vsnprintf(NULL, 0, event->fmt, args) + 1;
125 va_end(args);
c7b17051 126
64c57ea1 127 msg = malloc(len * sizeof(char));
8178adc6 128 if (!msg)
129 return NULL;
c7b17051 130
64c57ea1
BD
131 rc = vsnprintf(msg, len, event->fmt, *event->vap);
132 if (rc == -1 || rc >= len) {
133 free(msg);
8178adc6 134 return NULL;
64c57ea1
BD
135 }
136
8178adc6 137 return msg;
138}
139
140/*---------------------------------------------------------------------------*/
141static int log_append_syslog(const struct lxc_log_appender *appender,
142 struct lxc_log_event *event)
143{
144 char *msg;
145 const char *log_container_name;
146
147 if (!syslog_enable)
148 return 0;
149
150 log_container_name = lxc_log_get_container_name();
151
152 msg = lxc_log_get_va_msg(event);
153 if (!msg)
154 return 0;
155
64c57ea1 156 syslog(lxc_log_priority_to_syslog(event->priority),
8273ba47 157 "%s%s %s - %s:%s:%d - %s" ,
158 log_container_name ? log_container_name : "",
159 log_container_name ? ":" : "",
160 event->category,
161 event->locinfo->file, event->locinfo->func,
162 event->locinfo->line,
163 msg);
64c57ea1 164 free(msg);
c7b17051 165
64c57ea1
BD
166 return 0;
167}
168
d737c074
MN
169/*---------------------------------------------------------------------------*/
170static int log_append_stderr(const struct lxc_log_appender *appender,
171 struct lxc_log_event *event)
172{
c7b17051
CB
173 const char *log_container_name;
174
4b73005c 175 if (event->priority < LXC_LOG_LEVEL_ERROR)
d737c074
MN
176 return 0;
177
8178adc6 178 log_container_name = lxc_log_get_container_name();
c7b17051
CB
179
180 fprintf(stderr, "%s: %s%s", log_prefix,
8273ba47 181 log_container_name ? log_container_name : "",
182 log_container_name ? ": " : "");
c7b17051 183 fprintf(stderr, "%s: %s: %d ", event->locinfo->file,
8273ba47 184 event->locinfo->func, event->locinfo->line);
d737c074
MN
185 vfprintf(stderr, event->fmt, *event->vap);
186 fprintf(stderr, "\n");
c7b17051 187
d737c074
MN
188 return 0;
189}
190
cb8c5720 191/*---------------------------------------------------------------------------*/
8273ba47 192static int lxc_unix_epoch_to_utc(char *buf, size_t bufsize, const struct timespec *time)
65a9df89 193{
d86c0d08
CB
194 int64_t epoch_to_days, z, era, doe, yoe, year, doy, mp, day, month,
195 d_in_s, hours, h_in_s, minutes, seconds;
3a2c65f8 196 char nanosec[INTTYPE_TO_STRLEN(int64_t)];
65a9df89
CB
197 int ret;
198
199 /* See https://howardhinnant.github.io/date_algorithms.html for an
200 * explanation of the algorithm used here.
201 */
d86c0d08
CB
202
203 /* Convert Epoch in seconds to number of days. */
204 epoch_to_days = time->tv_sec / 86400;
205
206 /* Shift the Epoch from 1970-01-01 to 0000-03-01. */
207 z = epoch_to_days + 719468;
208
209 /* compute the era from the serial date by simply dividing by the number
210 * of days in an era (146097).
211 */
65a9df89 212 era = (z >= 0 ? z : z - 146096) / 146097;
d86c0d08
CB
213
214 /* The day-of-era (doe) can then be found by subtracting the era number
215 * times the number of days per era, from the serial date.
216 */
65a9df89 217 doe = (z - era * 146097);
d86c0d08
CB
218
219 /* From the day-of-era (doe), the year-of-era (yoe, range [0, 399]) can
220 * be computed.
221 */
65a9df89 222 yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
d86c0d08
CB
223
224 /* Given year-of-era, and era, one can now compute the year. */
86698d38 225 year = yoe + era * 400;
d86c0d08
CB
226
227 /* Also the day-of-year, again with the year beginning on Mar. 1, can be
228 * computed from the day-of-era and year-of-era.
229 */
65a9df89 230 doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
d86c0d08
CB
231
232 /* Given day-of-year, find the month number. */
65a9df89 233 mp = (5 * doy + 2) / 153;
d86c0d08
CB
234
235 /* From day-of-year and month-of-year we can now easily compute
236 * day-of-month.
237 */
65a9df89 238 day = doy - (153 * mp + 2) / 5 + 1;
d86c0d08
CB
239
240 /* Transform the month number from the [0, 11] / [Mar, Feb] system to
241 * the civil system: [1, 12] to find the correct month.
242 */
65a9df89 243 month = mp + (mp < 10 ? 3 : -9);
d86c0d08 244
86698d38
CB
245 /* The algorithm assumes that a year begins on 1 March, so add 1 before
246 * that. */
247 if (month < 3)
248 year++;
249
d86c0d08
CB
250 /* Transform days in the epoch to seconds. */
251 d_in_s = epoch_to_days * 86400;
252
253 /* To find the current hour simply substract the Epoch_to_days from the
254 * total Epoch and divide by the number of seconds in an hour.
255 */
65a9df89 256 hours = (time->tv_sec - d_in_s) / 3600;
d86c0d08
CB
257
258 /* Transform hours to seconds. */
65a9df89 259 h_in_s = hours * 3600;
d86c0d08 260
29fa2d33 261 /* Calculate minutes by subtracting the seconds for all days in the
d86c0d08
CB
262 * epoch and for all hours in the epoch and divide by the number of
263 * minutes in an hour.
264 */
65a9df89 265 minutes = (time->tv_sec - d_in_s - h_in_s) / 60;
d86c0d08 266
29fa2d33 267 /* Calculate the seconds by subtracting the seconds for all days in the
d86c0d08
CB
268 * epoch, hours in the epoch and minutes in the epoch.
269 */
65a9df89
CB
270 seconds = (time->tv_sec - d_in_s - h_in_s - (minutes * 60));
271
d86c0d08 272 /* Make string from nanoseconds. */
979a0d93
CB
273 ret = snprintf(nanosec, sizeof(nanosec), "%"PRId64, (int64_t)time->tv_nsec);
274 if (ret < 0 || ret >= sizeof(nanosec))
65a9df89 275 return -1;
d86c0d08
CB
276
277 /* Create final timestamp for the log and shorten nanoseconds to 3
278 * digit precision.
279 */
9d7468fd
CB
280 ret = snprintf(buf, bufsize,
281 "%" PRId64 "%02" PRId64 "%02" PRId64 "%02" PRId64
282 "%02" PRId64 "%02" PRId64 ".%.3s",
65a9df89
CB
283 year, month, day, hours, minutes, seconds, nanosec);
284 if (ret < 0 || (size_t)ret >= bufsize)
285 return -1;
286
287 return 0;
288}
289
c57dbb96
CB
290/* This function needs to make extra sure that it is thread-safe. We had some
291 * problems with that before. This especially involves time-conversion
292 * functions. I don't want to find any localtime() or gmtime() functions or
293 * relatives in here. Not even localtime_r() or gmtime_r() or relatives. They
294 * all fiddle with global variables and locking in various libcs. They cause
295 * deadlocks when liblxc is used multi-threaded and no matter how smart you
296 * think you are, you __will__ cause trouble using them.
297 * (As a short example how this can cause trouble: LXD uses forkstart to fork
298 * off a new process that runs the container. At the same time the go runtime
25fa6f8c 299 * LXD relies on does its own multi-threading thing which we can't control. The
c57dbb96
CB
300 * fork()ing + threading then seems to mess with the locking states in these
301 * time functions causing deadlocks.)
302 * The current solution is to be good old unix people and use the Epoch as our
303 * reference point and simply use the seconds and nanoseconds that have past
304 * since then. This relies on clock_gettime() which is explicitly marked MT-Safe
305 * with no restrictions! This way, anyone who is really strongly invested in
306 * getting the actual time the log entry was created, can just convert it for
307 * themselves. Our logging is mostly done for debugging purposes so don't try
308 * to make it pretty. Pretty might cost you thread-safety.
309 */
cb8c5720 310static int log_append_logfile(const struct lxc_log_appender *appender,
5fd8380b 311 struct lxc_log_event *event)
cb8c5720
CLG
312{
313 char buffer[LXC_LOG_BUFFER_SIZE];
e1378d35 314 char date_time[LXC_LOG_TIME_SIZE];
e0c19806
CB
315 int n;
316 ssize_t ret;
858377e4 317 int fd_to_use = -1;
8178adc6 318 const char *log_container_name;
42e56013 319
858377e4 320#ifndef NO_LXC_CONF
8178adc6 321 if (current_config)
c7b17051
CB
322 if (!lxc_log_use_global_fd)
323 fd_to_use = current_config->logfd;
858377e4
SH
324#endif
325
8178adc6 326 log_container_name = lxc_log_get_container_name();
327
858377e4
SH
328 if (fd_to_use == -1)
329 fd_to_use = lxc_log_fd;
330
331 if (fd_to_use == -1)
cb8c5720
CLG
332 return 0;
333
e1378d35 334 if (lxc_unix_epoch_to_utc(date_time, LXC_LOG_TIME_SIZE, &event->timestamp) < 0)
a9d41379 335 return -1;
c57dbb96
CB
336
337 n = snprintf(buffer, sizeof(buffer),
8273ba47 338 "%s%s%s %s %-8s %s - %s:%s:%d - ",
339 log_prefix,
340 log_container_name ? " " : "",
341 log_container_name ? log_container_name : "",
342 date_time,
343 lxc_log_priority_to_string(event->priority),
344 event->category,
345 event->locinfo->file, event->locinfo->func,
346 event->locinfo->line);
f6c79610
LZ
347 if (n < 0)
348 return n;
cb8c5720 349
6333c915 350 if ((size_t)n < STRARRAYLEN(buffer)) {
be5c06ec
CB
351 ret = vsnprintf(buffer + n, sizeof(buffer) - n, event->fmt, *event->vap);
352 if (ret < 0)
353 return 0;
354
355 n += ret;
356 }
b0a507d7
CB
357
358 if ((size_t)n >= sizeof(buffer))
6333c915 359 n = STRARRAYLEN(buffer);
cb8c5720
CLG
360
361 buffer[n] = '\n';
362
e0c19806
CB
363again:
364 ret = write(fd_to_use, buffer, n + 1);
365 if (ret < 0 && errno == EINTR)
366 goto again;
367
368 return ret;
cb8c5720
CLG
369}
370
5c7bfc02 371#if HAVE_DLOG
372static int log_append_dlog(const struct lxc_log_appender *appender,
373 struct lxc_log_event *event)
374{
de1c05f3 375 char *msg = lxc_log_get_va_msg(event);
376 const char *log_container_name = lxc_log_get_container_name();
5c7bfc02 377
de1c05f3 378 switch (event->priority) {
5c7bfc02 379 case LXC_LOG_LEVEL_TRACE:
380 case LXC_LOG_LEVEL_DEBUG:
de1c05f3 381 print_log(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > [%s] %s",
382 event->locinfo->file, event->locinfo->func, event->locinfo->line,
383 log_container_name ? log_container_name : "-",
384 msg ? msg : "-");
5c7bfc02 385 break;
386 case LXC_LOG_LEVEL_INFO:
de1c05f3 387 print_log(DLOG_INFO, LOG_TAG, "%s: %s(%d) > [%s] %s",
388 event->locinfo->file, event->locinfo->func, event->locinfo->line,
389 log_container_name ? log_container_name : "-",
390 msg ? msg : "-");
5c7bfc02 391 break;
392 case LXC_LOG_LEVEL_NOTICE:
393 case LXC_LOG_LEVEL_WARN:
de1c05f3 394 print_log(DLOG_WARN, LOG_TAG, "%s: %s(%d) > [%s] %s",
395 event->locinfo->file, event->locinfo->func, event->locinfo->line,
396 log_container_name ? log_container_name : "-",
397 msg ? msg : "-");
5c7bfc02 398 break;
399 case LXC_LOG_LEVEL_ERROR:
de1c05f3 400 print_log(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > [%s] %s",
401 event->locinfo->file, event->locinfo->func, event->locinfo->line,
402 log_container_name ? log_container_name : "-",
403 msg ? msg : "-");
5c7bfc02 404 break;
405 case LXC_LOG_LEVEL_CRIT:
406 case LXC_LOG_LEVEL_ALERT:
407 case LXC_LOG_LEVEL_FATAL:
de1c05f3 408 print_log(DLOG_FATAL, LOG_TAG, "%s: %s(%d) > [%s] %s",
409 event->locinfo->file, event->locinfo->func, event->locinfo->line,
410 log_container_name ? log_container_name : "-",
411 msg ? msg : "-");
5c7bfc02 412 break;
413 default:
414 break;
415 }
416
de1c05f3 417 free(msg);
5c7bfc02 418 return 0;
419}
420#endif
421
64c57ea1
BD
422static struct lxc_log_appender log_appender_syslog = {
423 .name = "syslog",
424 .append = log_append_syslog,
425 .next = NULL,
426};
427
d737c074
MN
428static struct lxc_log_appender log_appender_stderr = {
429 .name = "stderr",
430 .append = log_append_stderr,
431 .next = NULL,
432};
433
cb8c5720
CLG
434static struct lxc_log_appender log_appender_logfile = {
435 .name = "logfile",
436 .append = log_append_logfile,
441e4963 437 .next = NULL,
cb8c5720
CLG
438};
439
5c7bfc02 440#if HAVE_DLOG
441static struct lxc_log_appender log_appender_dlog = {
442 .name = "dlog",
443 .append = log_append_dlog,
444 .next = NULL,
445};
446#endif
447
cb8c5720
CLG
448static struct lxc_log_category log_root = {
449 .name = "root",
4b73005c 450 .priority = LXC_LOG_LEVEL_ERROR,
cb8c5720
CLG
451 .appender = NULL,
452 .parent = NULL,
453};
454
5c7bfc02 455#if HAVE_DLOG
456struct lxc_log_category lxc_log_category_lxc = {
457 .name = "lxc",
de1c05f3 458 .priority = LXC_LOG_LEVEL_TRACE,
5c7bfc02 459 .appender = &log_appender_dlog,
460 .parent = &log_root
461};
462#else
cb8c5720
CLG
463struct lxc_log_category lxc_log_category_lxc = {
464 .name = "lxc",
4b73005c 465 .priority = LXC_LOG_LEVEL_ERROR,
858377e4 466 .appender = &log_appender_logfile,
cb8c5720
CLG
467 .parent = &log_root
468};
5c7bfc02 469#endif
cb8c5720
CLG
470
471/*---------------------------------------------------------------------------*/
5e1e7aaf
SH
472static int build_dir(const char *name)
473{
1a0e70ac 474 char *e, *n, *p;
5e1e7aaf 475
202a334b 476 /* Make copy of the string since we'll be modifying it. */
1a0e70ac 477 n = strdup(name);
202a334b 478 if (!n)
5e1e7aaf 479 return -1;
5e1e7aaf
SH
480
481 e = &n[strlen(n)];
202a334b
CB
482 for (p = n + 1; p < e; p++) {
483 int ret;
484
5e1e7aaf
SH
485 if (*p != '/')
486 continue;
487 *p = '\0';
7d204776 488
202a334b
CB
489 ret = lxc_unpriv(mkdir(n, 0755));
490 if (ret && errno != EEXIST) {
491 SYSERROR("Failed to create directory %s", n);
492 free(n);
493 return -1;
5e1e7aaf 494 }
202a334b 495
5e1e7aaf
SH
496 *p = '/';
497 }
7d204776 498
5e1e7aaf
SH
499 free(n);
500 return 0;
501}
502
cb8c5720
CLG
503/*---------------------------------------------------------------------------*/
504static int log_open(const char *name)
505{
506 int fd;
507 int newfd;
508
202a334b
CB
509 fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0666));
510 if (fd < 0) {
6d1400b5 511 SYSERROR("Failed to open log file \"%s\"", name);
cb8c5720
CLG
512 return -1;
513 }
514
515 if (fd > 2)
516 return fd;
517
202a334b 518 newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDERR_FILENO);
cb8c5720 519 if (newfd == -1)
6d1400b5 520 SYSERROR("Failed to dup log fd %d", fd);
cb8c5720
CLG
521
522 close(fd);
523 return newfd;
524}
525
ab1bf971
DE
526/*
527 * Build the path to the log file
528 * @name : the name of the container
529 * @lxcpath : the lxcpath to use as a basename or NULL to use LOGPATH
ec64264d 530 * Returns malloced path on success, or NULL on failure
ab1bf971
DE
531 */
532static char *build_log_path(const char *name, const char *lxcpath)
5e1e7aaf
SH
533{
534 char *p;
202a334b
CB
535 int ret;
536 size_t len;
537 bool use_dir;
ee25a44f 538
74f052dd
SG
539 if (!name)
540 return NULL;
541
ee25a44f 542#if USE_CONFIGPATH_LOGS
202a334b 543 use_dir = true;
ee25a44f 544#else
202a334b 545 use_dir = false;
ee25a44f 546#endif
5e1e7aaf
SH
547
548 /*
ee25a44f
DE
549 * If USE_CONFIGPATH_LOGS is true or lxcpath is given, the resulting
550 * path will be:
5e1e7aaf 551 * '$logpath' + '/' + '$name' + '/' + '$name' + '.log' + '\0'
ab1bf971
DE
552 *
553 * If USE_CONFIGPATH_LOGS is false the resulting path will be:
554 * '$logpath' + '/' + '$name' + '.log' + '\0'
5e1e7aaf 555 */
ab1bf971 556 len = strlen(name) + 6; /* 6 == '/' + '.log' + '\0' */
ee25a44f 557 if (lxcpath)
202a334b 558 use_dir = true;
ee25a44f 559 else
ab1bf971 560 lxcpath = LOGPATH;
ee25a44f
DE
561
562 if (use_dir)
563 len += strlen(lxcpath) + 1 + strlen(name) + 1; /* add "/$container_name/" */
564 else
565 len += strlen(lxcpath) + 1;
7d204776 566
5e1e7aaf
SH
567 p = malloc(len);
568 if (!p)
569 return p;
ee25a44f
DE
570
571 if (use_dir)
572 ret = snprintf(p, len, "%s/%s/%s.log", lxcpath, name, name);
573 else
574 ret = snprintf(p, len, "%s/%s.log", lxcpath, name);
202a334b 575 if (ret < 0 || (size_t)ret >= len) {
5e1e7aaf
SH
576 free(p);
577 return NULL;
578 }
7d204776 579
5e1e7aaf
SH
580 return p;
581}
582
ab1bf971
DE
583/*
584 * This can be called:
585 * 1. when a program calls lxc_log_init with no logfile parameter (in which
46cc906d 586 * case the default is used). In this case lxc.loge can override this.
ab1bf971 587 * 2. when a program calls lxc_log_init with a logfile parameter. In this
46cc906d 588 * case we don't want lxc.log to override this.
589 * 3. When a lxc.log entry is found in config file.
ab1bf971
DE
590 */
591static int __lxc_log_set_file(const char *fname, int create_dirs)
592{
1a0e70ac
CB
593 /* we are overriding the default. */
594 if (lxc_log_fd != -1)
d9c9b180 595 lxc_log_close();
ab1bf971 596
97bc2422
CB
597 if (!fname)
598 return -1;
3f53c691
SH
599
600 if (strlen(fname) == 0) {
6edbfc86 601 log_fname = NULL;
03c6d266 602 return -1;
6edbfc86
SG
603 }
604
ab1bf971 605#if USE_CONFIGPATH_LOGS
1a0e70ac
CB
606 /* We don't build_dir for the default if the default is i.e.
607 * /var/lib/lxc/$container/$container.log.
608 */
ab1bf971
DE
609 if (create_dirs)
610#endif
611 if (build_dir(fname)) {
6d1400b5 612 SYSERROR("Failed to create dir for log file \"%s\"", fname);
ab1bf971
DE
613 return -1;
614 }
615
616 lxc_log_fd = log_open(fname);
617 if (lxc_log_fd == -1)
618 return -1;
619
620 log_fname = strdup(fname);
621 return 0;
622}
623
624static int _lxc_log_set_file(const char *name, const char *lxcpath, int create_dirs)
625{
626 char *logfile;
627 int ret;
628
629 logfile = build_log_path(name, lxcpath);
630 if (!logfile) {
7d204776 631 ERROR("Could not build log path");
ab1bf971
DE
632 return -1;
633 }
202a334b 634
ab1bf971
DE
635 ret = __lxc_log_set_file(logfile, create_dirs);
636 free(logfile);
637 return ret;
638}
5e1e7aaf 639
858377e4
SH
640/*
641 * lxc_log_init:
642 * Called from lxc front-end programs (like lxc-create, lxc-start) to
95db7d8c 643 * initialize the log defaults.
858377e4 644 */
202a334b 645int lxc_log_init(struct lxc_log *log)
cb8c5720 646{
5e1e7aaf 647 int ret;
202a334b 648 int lxc_priority = LXC_LOG_LEVEL_ERROR;
51cab631 649
03c6d266 650 if (!log)
651 return -1;
652
ab1bf971 653 if (lxc_log_fd != -1) {
202a334b 654 WARN("Log already initialized");
2312f31b 655 return 0;
ab1bf971 656 }
2312f31b 657
4b73005c
CB
658 if (log->level)
659 lxc_priority = lxc_log_priority_to_int(log->level);
51cab631 660
858377e4
SH
661 if (!lxc_loglevel_specified) {
662 lxc_log_category_lxc.priority = lxc_priority;
663 lxc_loglevel_specified = 1;
664 }
cb8c5720 665
03c6d266 666 if (!lxc_quiet_specified)
73b910a3 667 if (!log->quiet)
01db0197 668 lxc_log_category_lxc.appender->next = &log_appender_stderr;
441e4963 669
73b910a3 670 if (log->prefix)
671 lxc_log_set_prefix(log->prefix);
74476cf1 672
73b910a3 673 if (log->name)
674 log_vmname = strdup(log->name);
64c57ea1 675
73b910a3 676 if (log->file) {
677 if (strcmp(log->file, "none") == 0)
ab1bf971 678 return 0;
202a334b 679
73b910a3 680 ret = __lxc_log_set_file(log->file, 1);
03c6d266 681 if (ret < 0) {
682 ERROR("Failed to enable logfile");
683 return -1;
684 }
685
858377e4 686 lxc_log_use_global_fd = 1;
5e1e7aaf 687 } else {
74f052dd 688 /* if no name was specified, there nothing to do */
73b910a3 689 if (!log->name)
74f052dd
SG
690 return 0;
691
ab1bf971
DE
692 ret = -1;
693
73b910a3 694 if (!log->lxcpath)
695 log->lxcpath = LOGPATH;
e0b0b533 696
361e0e3c 697 /* try LOGPATH if lxcpath is the default for the privileged containers */
73b910a3 698 if (!geteuid() && strcmp(LXCPATH, log->lxcpath) == 0)
699 ret = _lxc_log_set_file(log->name, NULL, 0);
5e1e7aaf 700
ab1bf971
DE
701 /* try in lxcpath */
702 if (ret < 0)
73b910a3 703 ret = _lxc_log_set_file(log->name, log->lxcpath, 1);
ab1bf971
DE
704
705 /* try LOGPATH in case its writable by the caller */
706 if (ret < 0)
73b910a3 707 ret = _lxc_log_set_file(log->name, NULL, 0);
ab1bf971 708 }
5e1e7aaf 709
5e1e7aaf 710 /*
ab1bf971
DE
711 * If !file, that is, if the user did not request this logpath, then
712 * ignore failures and continue logging to console
5e1e7aaf 713 */
73b910a3 714 if (!log->file && ret != 0) {
7d204776 715 INFO("Ignoring failure to open default logfile");
5e1e7aaf
SH
716 ret = 0;
717 }
718
03c6d266 719 if (lxc_log_fd != -1) {
720 lxc_log_category_lxc.appender = &log_appender_logfile;
721 lxc_log_category_lxc.appender->next = &log_appender_stderr;
722 }
723
5e1e7aaf 724 return ret;
cb8c5720 725}
4a85ce2a 726
8273ba47 727void lxc_log_close(void)
728{
729 closelog();
730
731 free(log_vmname);
732 log_vmname = NULL;
733
734 if (lxc_log_fd == -1)
735 return;
736
737 close(lxc_log_fd);
738 lxc_log_fd = -1;
739
740 free(log_fname);
741 log_fname = NULL;
742}
743
744int lxc_log_syslog(int facility)
745{
746 struct lxc_log_appender *appender;
747
748 openlog(log_prefix, LOG_PID, facility);
749 if (!lxc_log_category_lxc.appender) {
750 lxc_log_category_lxc.appender = &log_appender_syslog;
751 return 0;
752 }
753
754 appender = lxc_log_category_lxc.appender;
755 /* Check if syslog was already added, to avoid creating a loop */
756 while (appender) {
757 if (appender == &log_appender_syslog) {
758 /* not an error: openlog re-opened the connection */
759 return 0;
760 }
761 appender = appender->next;
762 }
763
764 appender = lxc_log_category_lxc.appender;
765 while (appender->next != NULL)
766 appender = appender->next;
767 appender->next = &log_appender_syslog;
768
769 return 0;
770}
771
772inline void lxc_log_enable_syslog(void)
773{
774 syslog_enable = 1;
775}
776
4a85ce2a 777/*
46cc906d 778 * This is called when we read a lxc.log.level entry in a lxc.conf file. This
4a85ce2a
SH
779 * happens after processing command line arguments, which override the .conf
780 * settings. So only set the level if previously unset.
781 */
202a334b 782int lxc_log_set_level(int *dest, int level)
4a85ce2a 783{
4b73005c 784 if (level < 0 || level >= LXC_LOG_LEVEL_NOTSET) {
7d204776 785 ERROR("Invalid log priority %d", level);
4a85ce2a
SH
786 return -1;
787 }
7d204776 788
858377e4 789 *dest = level;
4a85ce2a
SH
790 return 0;
791}
792
202a334b 793inline int lxc_log_get_level(void)
ab1bf971 794{
ab1bf971
DE
795 return lxc_log_category_lxc.priority;
796}
797
202a334b 798bool lxc_log_has_valid_level(void)
fabf7361 799{
202a334b 800 int log_level;
7d204776 801
202a334b 802 log_level = lxc_log_get_level();
4b73005c 803 if (log_level < 0 || log_level >= LXC_LOG_LEVEL_NOTSET)
fabf7361 804 return false;
7d204776 805
fabf7361
QH
806 return true;
807}
808
4a85ce2a 809/*
ab1bf971
DE
810 * This is called when we read a lxc.logfile entry in a lxc.conf file. This
811 * happens after processing command line arguments, which override the .conf
812 * settings. So only set the file if previously unset.
4a85ce2a 813 */
202a334b 814int lxc_log_set_file(int *fd, const char *fname)
4a85ce2a 815{
202a334b 816 if (*fd >= 0) {
858377e4
SH
817 close(*fd);
818 *fd = -1;
819 }
820
202a334b 821 if (build_dir(fname))
858377e4 822 return -1;
858377e4
SH
823
824 *fd = log_open(fname);
202a334b
CB
825 if (*fd < 0)
826 return -1;
7d204776 827
858377e4 828 return 0;
4a85ce2a 829}
9ea87d5d 830
202a334b 831inline const char *lxc_log_get_file(void)
5e1e7aaf 832{
ab1bf971 833 return log_fname;
5e1e7aaf
SH
834}
835
202a334b 836inline void lxc_log_set_prefix(const char *prefix)
9ea87d5d 837{
6333c915 838 /* We don't care if the prefix is truncated. */
9de31d5a 839 (void)strlcpy(log_prefix, prefix, sizeof(log_prefix));
9ea87d5d
SH
840}
841
202a334b 842inline const char *lxc_log_get_prefix(void)
9ea87d5d 843{
ab1bf971 844 return log_prefix;
9ea87d5d 845}
6edbfc86 846
202a334b 847inline void lxc_log_options_no_override()
6edbfc86 848{
01db0197 849 lxc_quiet_specified = 1;
858377e4 850 lxc_loglevel_specified = 1;
6edbfc86 851}