1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
17 #include <sys/types.h>
23 #include "file_utils.h"
25 #include "lxccontainer.h"
26 #include "memory_utils.h"
30 #include "include/strlcpy.h"
40 /* We're logging in seconds and nanoseconds. Assuming that the underlying
41 * datatype is currently at maximum a 64bit integer, we have a date string that
42 * is of maximum length (2^64 - 1) * 2 = (21 + 21) = 42.
44 #define LXC_LOG_TIME_SIZE ((INTTYPE_TO_STRLEN(uint64_t)) * 2)
46 int lxc_log_fd
= -EBADF
;
47 static bool wants_syslog
= false;
48 static int lxc_quiet_specified
;
49 bool lxc_log_use_global_fd
= false;
50 static int lxc_loglevel_specified
;
52 static char log_prefix
[LXC_LOG_PREFIX_SIZE
] = "lxc";
53 static char *log_fname
= NULL
;
54 static char *log_vmname
= NULL
;
56 lxc_log_define(log
, lxc
);
58 static int lxc_log_priority_to_syslog(int priority
)
61 case LXC_LOG_LEVEL_FATAL
:
63 case LXC_LOG_LEVEL_ALERT
:
65 case LXC_LOG_LEVEL_CRIT
:
67 case LXC_LOG_LEVEL_ERROR
:
69 case LXC_LOG_LEVEL_WARN
:
71 case LXC_LOG_LEVEL_NOTICE
:
72 case LXC_LOG_LEVEL_NOTSET
:
74 case LXC_LOG_LEVEL_INFO
:
76 case LXC_LOG_LEVEL_TRACE
:
77 case LXC_LOG_LEVEL_DEBUG
:
85 static const char *lxc_log_get_container_name(void)
88 if (current_config
&& !log_vmname
)
89 return current_config
->name
;
95 int lxc_log_get_fd(void)
100 if (current_config
&& !lxc_log_use_global_fd
)
101 fd_log
= current_config
->logfd
;
109 static char *lxc_log_get_va_msg(struct lxc_log_event
*event
)
111 __do_free
char *msg
= NULL
;
116 return ret_set_errno(NULL
, EINVAL
);
118 va_copy(args
, *event
->vap
);
119 #pragma GCC diagnostic push
120 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
121 len
= vsnprintf(NULL
, 0, event
->fmt
, args
) + 1;
122 #pragma GCC diagnostic pop
125 msg
= malloc(len
* sizeof(char));
127 return ret_set_errno(NULL
, ENOMEM
);
129 #pragma GCC diagnostic push
130 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
131 rc
= vsnprintf(msg
, len
, event
->fmt
, *event
->vap
);
132 #pragma GCC diagnostic pop
133 if (rc
< 0 || rc
>= len
)
134 return ret_set_errno(NULL
, EIO
);
136 return move_ptr(msg
);
139 static int log_append_syslog(const struct lxc_log_appender
*appender
,
140 struct lxc_log_event
*event
)
142 __do_free
char *msg
= NULL
;
143 const char *log_container_name
;
148 log_container_name
= lxc_log_get_container_name();
150 msg
= lxc_log_get_va_msg(event
);
154 syslog(lxc_log_priority_to_syslog(event
->priority
),
155 "%s%s %s - %s:%s:%d - %s" ,
156 log_container_name
? log_container_name
: "",
157 log_container_name
? ":" : "",
159 event
->locinfo
->file
, event
->locinfo
->func
,
160 event
->locinfo
->line
,
166 static int log_append_stderr(const struct lxc_log_appender
*appender
,
167 struct lxc_log_event
*event
)
169 const char *log_container_name
;
171 if (event
->priority
< LXC_LOG_LEVEL_ERROR
)
174 log_container_name
= lxc_log_get_container_name();
176 fprintf(stderr
, "%s: %s%s", log_prefix
,
177 log_container_name
? log_container_name
: "",
178 log_container_name
? ": " : "");
179 fprintf(stderr
, "%s: %s: %d ", event
->locinfo
->file
,
180 event
->locinfo
->func
, event
->locinfo
->line
);
181 #pragma GCC diagnostic push
182 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
183 vfprintf(stderr
, event
->fmt
, *event
->vap
);
184 #pragma GCC diagnostic pop
185 fprintf(stderr
, "\n");
190 static int lxc_unix_epoch_to_utc(char *buf
, size_t bufsize
, const struct timespec
*time
)
192 int64_t epoch_to_days
, z
, era
, doe
, yoe
, year
, doy
, mp
, day
, month
,
193 d_in_s
, hours
, h_in_s
, minutes
, seconds
;
194 char nanosec
[INTTYPE_TO_STRLEN(int64_t)];
198 * See https://howardhinnant.github.io/date_algorithms.html for an
199 * explanation of the algorithm used here.
202 /* Convert Epoch in seconds to number of days. */
203 epoch_to_days
= time
->tv_sec
/ 86400;
205 /* Shift the Epoch from 1970-01-01 to 0000-03-01. */
206 z
= epoch_to_days
+ 719468;
209 * Compute the era from the serial date by simply dividing by the number
210 * of days in an era (146097).
212 era
= (z
>= 0 ? z
: z
- 146096) / 146097;
215 * The day-of-era (doe) can then be found by subtracting the era number
216 * times the number of days per era, from the serial date.
218 doe
= (z
- era
* 146097);
221 * From the day-of-era (doe), the year-of-era (yoe, range [0, 399]) can
224 yoe
= (doe
- doe
/ 1460 + doe
/ 36524 - doe
/ 146096) / 365;
226 /* Given year-of-era, and era, one can now compute the year. */
227 year
= yoe
+ era
* 400;
230 * Also the day-of-year, again with the year beginning on Mar. 1, can be
231 * computed from the day-of-era and year-of-era.
233 doy
= doe
- (365 * yoe
+ yoe
/ 4 - yoe
/ 100);
235 /* Given day-of-year, find the month number. */
236 mp
= (5 * doy
+ 2) / 153;
239 * From day-of-year and month-of-year we can now easily compute
242 day
= doy
- (153 * mp
+ 2) / 5 + 1;
245 * Transform the month number from the [0, 11] / [Mar, Feb] system to
246 * the civil system: [1, 12] to find the correct month.
248 month
= mp
+ (mp
< 10 ? 3 : -9);
251 * The algorithm assumes that a year begins on 1 March, so add 1 before
257 /* Transform days in the epoch to seconds. */
258 d_in_s
= epoch_to_days
* 86400;
261 * To find the current hour simply substract the Epoch_to_days from the
262 * total Epoch and divide by the number of seconds in an hour.
264 hours
= (time
->tv_sec
- d_in_s
) / 3600;
266 /* Transform hours to seconds. */
267 h_in_s
= hours
* 3600;
270 * Calculate minutes by subtracting the seconds for all days in the
271 * epoch and for all hours in the epoch and divide by the number of
272 * minutes in an hour.
274 minutes
= (time
->tv_sec
- d_in_s
- h_in_s
) / 60;
277 * Calculate the seconds by subtracting the seconds for all days in the
278 * epoch, hours in the epoch and minutes in the epoch.
280 seconds
= (time
->tv_sec
- d_in_s
- h_in_s
- (minutes
* 60));
282 /* Make string from nanoseconds. */
283 ret
= strnprintf(nanosec
, sizeof(nanosec
), "%"PRId64
, (int64_t)time
->tv_nsec
);
285 return ret_errno(EIO
);
288 * Create final timestamp for the log and shorten nanoseconds to 3
291 ret
= strnprintf(buf
, bufsize
,
292 "%" PRId64
"%02" PRId64
"%02" PRId64
"%02" PRId64
293 "%02" PRId64
"%02" PRId64
".%.3s",
294 year
, month
, day
, hours
, minutes
, seconds
, nanosec
);
296 return ret_errno(EIO
);
302 * This function needs to make extra sure that it is thread-safe. We had some
303 * problems with that before. This especially involves time-conversion
304 * functions. I don't want to find any localtime() or gmtime() functions or
305 * relatives in here. Not even localtime_r() or gmtime_r() or relatives. They
306 * all fiddle with global variables and locking in various libcs. They cause
307 * deadlocks when liblxc is used multi-threaded and no matter how smart you
308 * think you are, you __will__ cause trouble using them.
309 * (As a short example how this can cause trouble: LXD uses forkstart to fork
310 * off a new process that runs the container. At the same time the go runtime
311 * LXD relies on does its own multi-threading thing which we can't control. The
312 * fork()ing + threading then seems to mess with the locking states in these
313 * time functions causing deadlocks.)
314 * The current solution is to be good old unix people and use the Epoch as our
315 * reference point and simply use the seconds and nanoseconds that have past
316 * since then. This relies on clock_gettime() which is explicitly marked MT-Safe
317 * with no restrictions! This way, anyone who is really strongly invested in
318 * getting the actual time the log entry was created, can just convert it for
319 * themselves. Our logging is mostly done for debugging purposes so don't try
320 * to make it pretty. Pretty might cost you thread-safety.
322 static int log_append_logfile(const struct lxc_log_appender
*appender
,
323 struct lxc_log_event
*event
)
325 int fd_to_use
= -EBADF
;
326 char buffer
[LXC_LOG_BUFFER_SIZE
];
327 char date_time
[LXC_LOG_TIME_SIZE
];
330 const char *log_container_name
;
333 if (current_config
&& !lxc_log_use_global_fd
)
334 fd_to_use
= current_config
->logfd
;
337 log_container_name
= lxc_log_get_container_name();
340 fd_to_use
= lxc_log_fd
;
345 ret
= lxc_unix_epoch_to_utc(date_time
, LXC_LOG_TIME_SIZE
, &event
->timestamp
);
350 * We allow truncation here which is why we use snprintf() directly
351 * instead of strnprintf().
353 n
= snprintf(buffer
, sizeof(buffer
),
354 "%s%s%s %s %-8s %s - %s:%s:%d - ",
356 log_container_name
? " " : "",
357 log_container_name
? log_container_name
: "",
359 lxc_log_priority_to_string(event
->priority
),
361 event
->locinfo
->file
, event
->locinfo
->func
,
362 event
->locinfo
->line
);
364 return ret_errno(EIO
);
366 if ((size_t)n
< STRARRAYLEN(buffer
)) {
367 #pragma GCC diagnostic push
368 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
369 ret
= vsnprintf(buffer
+ n
, sizeof(buffer
) - n
, event
->fmt
, *event
->vap
);
370 #pragma GCC diagnostic pop
377 if ((size_t)n
>= sizeof(buffer
))
378 n
= STRARRAYLEN(buffer
);
382 return lxc_write_nointr(fd_to_use
, buffer
, n
+ 1);
386 static int log_append_dlog(const struct lxc_log_appender
*appender
,
387 struct lxc_log_event
*event
)
389 __do_free
char *msg
= NULL
;
390 const char *log_container_name
;
392 log_container_name
= lxc_log_get_container_name();
393 msg
= lxc_log_get_va_msg(event
);
395 switch (event
->priority
) {
396 case LXC_LOG_LEVEL_TRACE
:
397 case LXC_LOG_LEVEL_DEBUG
:
398 print_log(DLOG_DEBUG
, LOG_TAG
, "%s: %s(%d) > [%s] %s",
399 event
->locinfo
->file
, event
->locinfo
->func
, event
->locinfo
->line
,
400 log_container_name
? log_container_name
: "-",
403 case LXC_LOG_LEVEL_INFO
:
404 print_log(DLOG_INFO
, LOG_TAG
, "%s: %s(%d) > [%s] %s",
405 event
->locinfo
->file
, event
->locinfo
->func
, event
->locinfo
->line
,
406 log_container_name
? log_container_name
: "-",
409 case LXC_LOG_LEVEL_NOTICE
:
410 case LXC_LOG_LEVEL_WARN
:
411 print_log(DLOG_WARN
, LOG_TAG
, "%s: %s(%d) > [%s] %s",
412 event
->locinfo
->file
, event
->locinfo
->func
, event
->locinfo
->line
,
413 log_container_name
? log_container_name
: "-",
416 case LXC_LOG_LEVEL_ERROR
:
417 print_log(DLOG_ERROR
, LOG_TAG
, "%s: %s(%d) > [%s] %s",
418 event
->locinfo
->file
, event
->locinfo
->func
, event
->locinfo
->line
,
419 log_container_name
? log_container_name
: "-",
422 case LXC_LOG_LEVEL_CRIT
:
423 case LXC_LOG_LEVEL_ALERT
:
424 case LXC_LOG_LEVEL_FATAL
:
425 print_log(DLOG_FATAL
, LOG_TAG
, "%s: %s(%d) > [%s] %s",
426 event
->locinfo
->file
, event
->locinfo
->func
, event
->locinfo
->line
,
427 log_container_name
? log_container_name
: "-",
438 static struct lxc_log_appender log_appender_syslog
= {
440 .append
= log_append_syslog
,
444 static struct lxc_log_appender log_appender_stderr
= {
446 .append
= log_append_stderr
,
450 static struct lxc_log_appender log_appender_logfile
= {
452 .append
= log_append_logfile
,
457 static struct lxc_log_appender log_appender_dlog
= {
459 .append
= log_append_dlog
,
464 static struct lxc_log_category log_root
= {
466 .priority
= LXC_LOG_LEVEL_ERROR
,
472 struct lxc_log_category lxc_log_category_lxc
= {
474 .priority
= LXC_LOG_LEVEL_TRACE
,
475 .appender
= &log_appender_dlog
,
479 struct lxc_log_category lxc_log_category_lxc
= {
481 .priority
= LXC_LOG_LEVEL_ERROR
,
482 .appender
= &log_appender_logfile
,
487 static int build_dir(const char *name
)
489 __do_free
char *n
= NULL
;
492 if (is_empty_string(name
))
493 return ret_errno(EINVAL
);
495 /* Make copy of the string since we'll be modifying it. */
498 return ret_errno(ENOMEM
);
501 for (p
= n
+ 1; p
< e
; p
++) {
508 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
509 ret
= lxc_unpriv(mkdir(n
, 0755));
511 ret
= errno
= EEXIST
;
512 #endif /*!FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
514 if (ret
&& errno
!= EEXIST
)
515 return log_error_errno(-errno
, errno
, "Failed to create directory \"%s\"", n
);
521 static int log_open(const char *name
)
524 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
525 __do_close
int fd
= -EBADF
;
527 fd
= lxc_unpriv(open(name
, O_CREAT
| O_WRONLY
| O_APPEND
| O_CLOEXEC
, 0660));
529 return log_error_errno(-errno
, errno
, "Failed to open log file \"%s\"", name
);
534 newfd
= fcntl(fd
, F_DUPFD_CLOEXEC
, STDERR_FILENO
);
536 return log_error_errno(-errno
, errno
, "Failed to dup log fd %d", fd
);
537 #endif /* !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
542 * Build the path to the log file
543 * @name : the name of the container
544 * @lxcpath : the lxcpath to use as a basename or NULL to use LOGPATH
545 * Returns malloced path on success, or NULL on failure
547 static char *build_log_path(const char *name
, const char *lxcpath
)
549 __do_free
char *p
= NULL
;
555 return ret_set_errno(NULL
, EINVAL
);
557 #if USE_CONFIGPATH_LOGS
564 * If USE_CONFIGPATH_LOGS is true or lxcpath is given, the resulting
566 * '$logpath' + '/' + '$name' + '/' + '$name' + '.log' + '\0'
568 * If USE_CONFIGPATH_LOGS is false the resulting path will be:
569 * '$logpath' + '/' + '$name' + '.log' + '\0'
571 len
= strlen(name
) + 6; /* 6 == '/' + '.log' + '\0' */
578 len
+= strlen(lxcpath
) + 1 + strlen(name
) + 1; /* add "/$container_name/" */
580 len
+= strlen(lxcpath
) + 1;
584 return ret_set_errno(NULL
, ENOMEM
);
587 ret
= strnprintf(p
, len
, "%s/%s/%s.log", lxcpath
, name
, name
);
589 ret
= strnprintf(p
, len
, "%s/%s.log", lxcpath
, name
);
591 return ret_set_errno(NULL
, EIO
);
597 * This can be called:
598 * 1. when a program calls lxc_log_init with no logfile parameter (in which
599 * case the default is used). In this case lxc.loge can override this.
600 * 2. when a program calls lxc_log_init with a logfile parameter. In this
601 * case we don't want lxc.log to override this.
602 * 3. When a lxc.log entry is found in config file.
604 static int __lxc_log_set_file(const char *fname
, int create_dirs
)
606 /* we are overriding the default. */
610 if (is_empty_string(fname
))
611 return ret_errno(EINVAL
);
613 if (strlen(fname
) == 0) {
615 return ret_errno(EINVAL
);
618 #if USE_CONFIGPATH_LOGS
619 /* We don't build_dir for the default if the default is i.e.
620 * /var/lib/lxc/$container/$container.log.
624 if (build_dir(fname
))
625 return log_error_errno(-errno
, errno
, "Failed to create dir for log file \"%s\"", fname
);
627 lxc_log_fd
= log_open(fname
);
631 log_fname
= strdup(fname
);
635 static int _lxc_log_set_file(const char *name
, const char *lxcpath
, int create_dirs
)
637 __do_free
char *logfile
= NULL
;
639 logfile
= build_log_path(name
, lxcpath
);
641 return log_error_errno(-errno
, errno
, "Could not build log path");
643 return __lxc_log_set_file(logfile
, create_dirs
);
648 * Called from lxc front-end programs (like lxc-create, lxc-start) to
649 * initialize the log defaults.
651 int lxc_log_init(struct lxc_log
*log
)
654 int lxc_priority
= LXC_LOG_LEVEL_ERROR
;
657 return ret_errno(EINVAL
);
660 return log_warn_errno(0, EOPNOTSUPP
, "Log already initialized");
663 lxc_priority
= lxc_log_priority_to_int(log
->level
);
665 if (!lxc_loglevel_specified
) {
666 lxc_log_category_lxc
.priority
= lxc_priority
;
667 lxc_loglevel_specified
= 1;
670 if (!lxc_quiet_specified
)
672 lxc_log_category_lxc
.appender
->next
= &log_appender_stderr
;
675 lxc_log_set_prefix(log
->prefix
);
678 log_vmname
= strdup(log
->name
);
681 if (strequal(log
->file
, "none"))
684 ret
= __lxc_log_set_file(log
->file
, 1);
686 return log_error_errno(-1, errno
, "Failed to enable logfile");
688 lxc_log_use_global_fd
= true;
690 /* if no name was specified, there nothing to do */
697 log
->lxcpath
= LOGPATH
;
699 /* try LOGPATH if lxcpath is the default for the privileged containers */
700 if (!geteuid() && strequal(LXCPATH
, log
->lxcpath
))
701 ret
= _lxc_log_set_file(log
->name
, NULL
, 0);
705 ret
= _lxc_log_set_file(log
->name
, log
->lxcpath
, 1);
707 /* try LOGPATH in case its writable by the caller */
709 ret
= _lxc_log_set_file(log
->name
, NULL
, 0);
713 * If !file, that is, if the user did not request this logpath, then
714 * ignore failures and continue logging to console
716 if (!log
->file
&& ret
!= 0) {
717 INFO("Ignoring failure to open default logfile");
721 if (lxc_log_fd
>= 0) {
722 lxc_log_category_lxc
.appender
= &log_appender_logfile
;
723 lxc_log_category_lxc
.appender
->next
= &log_appender_stderr
;
729 void lxc_log_close(void)
733 free_disarm(log_vmname
);
735 close_prot_errno_disarm(lxc_log_fd
);
737 free_disarm(log_fname
);
740 int lxc_log_syslog(int facility
)
742 struct lxc_log_appender
*appender
;
744 openlog(log_prefix
, LOG_PID
, facility
);
745 if (!lxc_log_category_lxc
.appender
) {
746 lxc_log_category_lxc
.appender
= &log_appender_syslog
;
750 appender
= lxc_log_category_lxc
.appender
;
751 /* Check if syslog was already added, to avoid creating a loop */
753 /* not an error: openlog re-opened the connection */
754 if (appender
== &log_appender_syslog
)
756 appender
= appender
->next
;
759 appender
= lxc_log_category_lxc
.appender
;
760 while (appender
->next
!= NULL
)
761 appender
= appender
->next
;
762 appender
->next
= &log_appender_syslog
;
767 void lxc_log_syslog_enable(void)
772 void lxc_log_syslog_disable(void)
774 wants_syslog
= false;
778 * This is called when we read a lxc.log.level entry in a lxc.conf file. This
779 * happens after processing command line arguments, which override the .conf
780 * settings. So only set the level if previously unset.
782 int lxc_log_set_level(int *dest
, int level
)
784 if (level
< 0 || level
>= LXC_LOG_LEVEL_NOTSET
)
785 return log_error_errno(-EINVAL
, EINVAL
, "Invalid log priority %d", level
);
791 int lxc_log_get_level(void)
793 int level
= LXC_LOG_LEVEL_NOTSET
;
797 level
= current_config
->loglevel
;
799 if (level
== LXC_LOG_LEVEL_NOTSET
)
800 level
= lxc_log_category_lxc
.priority
;
805 bool lxc_log_has_valid_level(void)
809 log_level
= lxc_log_get_level();
810 if (log_level
< 0 || log_level
>= LXC_LOG_LEVEL_NOTSET
)
811 return ret_set_errno(false, EINVAL
);
817 * This is called when we read a lxc.logfile entry in a lxc.conf file. This
818 * happens after processing command line arguments, which override the .conf
819 * settings. So only set the file if previously unset.
821 int lxc_log_set_file(int *fd
, const char *fname
)
824 close_prot_errno_disarm(*fd
);
826 if (is_empty_string(fname
))
827 return ret_errno(EINVAL
);
829 if (build_dir(fname
))
832 *fd
= log_open(fname
);
838 inline const char *lxc_log_get_file(void)
843 inline void lxc_log_set_prefix(const char *prefix
)
845 /* We don't care if the prefix is truncated. */
846 (void)strlcpy(log_prefix
, prefix
, sizeof(log_prefix
));
849 inline const char *lxc_log_get_prefix(void)
854 inline void lxc_log_options_no_override(void)
856 lxc_quiet_specified
= 1;
857 lxc_loglevel_specified
= 1;