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