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