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